我需要在记事本++中使用 tasm/tlink/dosbox 显示 3 位数的答案

I need to show 3 digit answer Using tasm/tlink/dosbox in notepad++

如何显示 3 位数的答案?

注意:我在加数和被加数中需要以 3 为基数,因为答案需要以 3 为基数,我该如何显示?我正在使用记事本++,然后是 tasm add.asm / tlink add / add。执行程序。我是 dosbox 的新手,所以只想学习如何在基数 3 中显示 3 位数的答案。

我在记事本++中的代码:

.model small
.stack 100h
.data
    
    Spc     db 0dh,0ah, " $"                                                ;New Line
    ErAd31  db 0dh,0ah, "Input only number to proceed [00-22 only]. $"      ;Error Input Addition Addend and Augend
    ErAd32  db 0dh,0ah, "Input only [Y/y] Add Again [N/n] No. $"            ;Error Input Add Again
    
    ;Bases Calculation in Calculator
    BsA31   db 0dh,0ah, "   Base 03 Addition "                          ;Addition Base 03
            db 0dh,0ah, " "
            db 0dh,0ah, "Addend[00-22]:  $"
    BsA32   db 0dh,0ah, "Augend[00-22]:  $"
    
    SumA    db 0dh,0ah, "   Sum is    :  $"                             ;Sum
    AgA     db 0dh,0ah,0dh,0ah, "Add Again[Y/N]? : $"                   ;Sum Again
    
    ;Calculation Logic
    Dg11    db 0
    Dg12    db 0
    NoAd1   db 0
    NoAd2   db 0
    SumAd   db 0
    
.code
main proc
    
    mov ax,@data                    ;initialize ds
    mov ds,ax
    
    AdBs3:
        mov ah,09h
        lea dx, Spc
        int 21h
        
        lea dx, BsA31               ;Addend
        int 21h
        mov ah,01h
        int 21h                     ;1st Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg11,al
        
        mov ah,01h
        int 21h                     ;2nd Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg12,al
        
        mov al, Dg11
        mov bl,10h
        mul bl
        
        mov NoAd1,al
        mov al,Dg12
        add NoAd1,al
        jmp AdBs32
    
    ErrAd31:
        mov ah,09h
        lea dx, Spc
        int 21h
        
        lea dx, ErAd31
        int 21h
        
        jmp AdAgain
        
    Ad1:
        cmp al, 59h or 79h
        je AdBs3
        
    AdBs32:
        
        mov ah,09h
        lea dx, BsA32               ;Augend
        int 21h
        mov ah,01h
        int 21h                     ;1st Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg11,al
        
        mov ah,01h
        int 21h                     ;2nd Digit
        
        cmp al,29h
        jle ErrAd31
        cmp al,33h
        jge ErrAd31
        
        sub al,30h
        mov Dg12,al
        
        mov al, Dg11
        mov bl,10h
        mul bl
        
        mov NoAd2,al
        mov al,Dg12
        add NoAd2,al
        
        ;Addition
        mov bl, NoAd1
        add bl, NoAd2
        mov cx,bx
        add cx,3210h
        
        mov ah,09h
        lea dx, SumA
        int 21h
        mov ah,02h
        mov dl,ch
        int 21h
        mov dl,cl
        int 21h
        
        jmp AdAgain
    
    AdAgain:
        mov ah,09h
        lea dx, Spc
        int 21h
        
        lea dx, AgA
        int 21h
        mov ah,01h
        int 21h
        
        cmp al, 59h or 79h
        je Ad1
        cmp al, 4Eh or 6Eh
        je AdOut
        
    AdOut:
        mov ah,4Ch                      ;end here
        int 21h
    
main endp
end main

需要输出:

Base 03 Addition

Addend[00-22]: 22
Augend[00-22]: 22
    Sum is   :121

Add Again[Y/N]? : N
cmp al, 29h       <================
jle ErrAd31
cmp al, 33h
jge ErrAd31

mov al, Dg11
mov bl, 10h       <================
mul bl

mov bl, NoAd1
add bl, NoAd2
mov cx, bx
add cx, 3210h     <================

您似乎无法使用 十六进制 数字系统!

  • 要检查输入数字的有效性,您应该与 2Fh 而不是 29h 进行比较。您忘记了十六进制也使用 A、B、C、D、E 和 F 作为数字。 “0”正下方的ASCII码是2Fh(因为“0”的ASCII码是30h)

  • 要转换以 3 为基数的输入,乘法应使用 3,而不是 10h,后者实际上等于 16。

  • 我不知道你认为这个 add cx, 3210h 会做什么。


how to show 3 digit answer in base 3.

以 3 为基数显示数字与以 10 为基数显示数字没有区别。 我从 Displaying numbers with DOS 的回答中复制了下一段代码。我将 mov bx, 10 更改为 mov bx, 3 等瞧...

    mov     al, NoAd1
    add     al, NoAd2
    mov     ah, 0
    ; Your number is in AX
    mov     bx, 3          ; CONST
    xor     cx, cx         ; Reset counter
.a: xor     dx, dx         ; Setup for division DX:AX / BX
    div     bx             ; -> AX is Quotient, Remainder DX=[0,2]
    push    dx             ; (1) Save remainder for now
    inc     cx             ; One more digit
    test    ax, ax         ; Is quotient zero?
    jnz     .a             ; No, use as next dividend
.b: pop     dx             ; (1)
    add     dl, "0"        ; Turn into character [0,2] -> ["0","2"]
    mov     ah, 02h        ; DOS.DisplayCharacter
    int     21h

AdAgain:

重复或退出程序很麻烦

  mov ah,01h
  int 21h
  cmp al, 59h or 79h
  je Ad1
  cmp al, 4Eh or 6Eh
  je AdOut  
AdOut:
  • 这种 or 的使用不提供 UCase 和 LCase 之间的选择。
  • 由于目标距离太远,使用条件跳转到顶部迫使您引入中间标签。
  • 如果用户按下上述键中的 none,您仍然会退出程序。那何必跟“N”或“n”比较呢?

更好用:

AdAgain:
    mov ah, 09h
    lea dx, Spc
    int 21h
    lea dx, AgA    ; "Continue?"
    int 21h

.z: mov ah, 01h
    int 21h
    or  al, 32     ; Make LCase
    cmp al, "n"    ; 6Eh
    je  AdOut
    cmp al, "y"    ; 79h
    jne .z         ; (*)
    jmp AdBs3      ; (**)
        
AdOut:

(*) 用户必须回答“N”、“n”、“Y”或“y”,否则问题会重复。
(**) 这个jmp可以一路跳到最上面。您不再需要中间标签 Ad1.