Math x86汇编(TASM)中两个数字的加法或减法

Math x86汇编(TASM)中两个数字的加法或减法,math,assembly,x86,tasm,Math,Assembly,X86,Tasm,我试图在汇编中编写一个程序,以加号或减号作为第一个输入(决定是否同时加号或减号两个数字),然后取两个2位数字,加/减并显示结果。到目前为止,我有以下代码,但在输出中遇到了问题。我知道在下面的代码片段中,它只是显示一个字符,但我希望它显示实际的输出,但我不知道如何,尝试使用正常的字符串显示中断不起作用,因为num2或al的大小与dx(输出字符串寄存器)的大小不匹配 以下是一个过程(NASM语法),它将打印任何无符号16位整数: ; Converts the integer value in AX

我试图在汇编中编写一个程序,以加号或减号作为第一个输入(决定是否同时加号或减号两个数字),然后取两个2位数字,加/减并显示结果。到目前为止,我有以下代码,但在输出中遇到了问题。我知道在下面的代码片段中,它只是显示一个字符,但我希望它显示实际的输出,但我不知道如何,尝试使用正常的字符串显示中断不起作用,因为num2或al的大小与dx(输出字符串寄存器)的大小不匹配

以下是一个过程(NASM语法),它将打印任何无符号16位整数:

; Converts the integer value in AX to a string in
; decimal representation and prints it.
; The digits are placed in a string buffer in reverse
; order - i.e. for the value 123, '3' would be placed
; last in the buffer, then '2' before that, and '1'
; before that, so that we'd end up with the string "123".
print_int:
  mov byte [buffer+9],'$'   ; add a string terminator at the end of the buffer
  lea si,[buffer+9]
  mov bx,10             ; divisor      
print_loop:
  xor dx,dx             ; clear dx prior to dividing dx:ax by bx
  div bx                ; AX /= 10
  add dl,'0'            ; take the remainder of the division and convert it from 0..9 -> '0'..'9'
  dec si                ; store characters in reverse order
  mov [si],dl
  test ax,ax
  jnz print_loop        ; repeat until AX==0 
  mov ah,9              ; print string
  mov dx,si
  int 21h
  ret

buffer: resb 10

我注意到你的程序中有很多重复的代码。如果您在程序中只读取一次输入的数字,然后根据用户指定的运算符对其执行相应的操作,则会更好。

谢谢您的帮助!对于我的代码,我找到了一种非常有效的方法。见下文:

关于重复代码: 是的,我意识到(这实际上不是我的代码,这是一个需要修复的朋友),我修复了代码,并对其进行了大量程序化,以尽量减少代码的重复使用。结果就是这里的最终程序: 我知道代码并不完美,可以进行许多性能改进,但结果是一个执行时间正常的工作程序

.MODEL SMALL
.STACK 100h
.DATA

choice_msg  db 13,10,'Addition or Subtraction?',13,10,'$' 
first_msg   db 13,10,'Enter the first number:',13,10,'$'
second_msg  db 13,10,'Enter the second number:',13,10,'$'
result_msg  db 13,10,'The result is:',13,10,'$'
new_line    db 13,10,'$'
val1        db ?
num1        db ?
num2        db ?
num3        db ?        ; purely a buffer variable 
ten         db 10   
t1          db 0
t2          db 0     
result      db 0

.CODE                   ;where the code is written
start:  

    mov ax, @data           ;Moves the address of the variables under .DATA into ax
    mov ds,ax           ;moves ax into ds. the two lines allow you to display string using the 21h interrupt sequence 9

    mov ah,09
    mov dx, offset choice_msg
    int 21h             ;displays the string in choice_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01

    cmp al,'+'          ;compares the entered value in with "+"
    jne subtraction         ;if the enterd value is "+" then it jumps to addition else it jumps to subtraction

addition: 

    call read           ;Read the input
    call endl           ;output new line

    mov bl, num2        ;move the value of num 2 into bl

    add num1,bl         ;adds num2 and num1 to form the sum1
    mov al, num1        ;mov num1 to al
    mov result, al      ;store the result of the sum in result

    call write          ;write the output 
    jmp exit

subtraction:

    call read           ;Read the input
    call endl           ;output new line

    mov bl, num2        ;move value of num2 to bl

    sub num1,bl         ;subtracts the value in num2 from the value in num1
    mov al, num1        ;move result to a register
    mov result, al      ;move the result of the subtraction to result

    call write          ;display result with write procedure
    jmp exit


    ;-----------------------
    ;procedure declarations: 

    proc endl

        mov ah,09
        mov dx, offset new_line
        int 21h             ;goes to next line, i.e. "enter"

        ret

    endp


    proc read


        mov ah,09
        mov dx, offset first_msg
        int 21h             ;displays the string in first_msg

        mov ah,01           ;read char
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the vaule in the al
        mov num1,al         ;moves the value in the al to the variable num1

        mov ah,01           ;read second char
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num2,al         ;moves the value in the al to the variable num2

        mov al,num1         ;moves the value in num1 into the al
        mul ten             ;multiplies the value in the al by ten
        add al,num2         ;adds the value in num2 to the al, to get the two-digit number
        mov num1,al         ;moves the two digit value into

        call endl

        mov ah,09
        mov dx, offset second_msg   ;displays the string in second_msg
        int 21h             

        mov ah,01
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num2,al         ;moves the new value in the al into the variable num2

        mov ah,01
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num3,al         ;moves the new value in the al into the variable num3

        mov al,num2         ;moves the value in num2 into the al
        mul ten             ;multiplies the value in the al by ten
        add al,num3         ;adds the value in num3 to the al, to get a two-digit number
        mov num2,al         ;moves the value in the al into the variable num2

        ret                 ;first number in num1, second in num2    
    endp


    ;The write procedure writes the decimal stored in result.
    ;by dividing by ten it seperates the two digits as quotient
    ;and remainder. Then it outputs the quotient and remainder
    ;in ascii form.
    proc write
            mov dx,offset result_msg
            mov ah,09h
            int 21h         ;display the result_msg string

            mov al,result   ;move the result from add/sub to al
            mov ah,00       ;initialize ah
            div ten         ;div al by ten, quotient is in al 
                            ;remainder is stored in ah.

            mov dl,ah       ;move the remainder to dl
            mov t2,dl       ;store the remainder in t2

            mov dl,al       ;move quotient into dl
            add dl,48       ;add 48 to dl, to convert it to ascii
            mov ah,02h      ;char display interupt code
            int 21h         ;display char in dl register

            mov dl,t2       ;move remainder to t2
            add dl,48       ;convert it to ascii by adding 48
            mov ah,02h      ;display character in dl interupt code
            int 21h         ;diplays contents of dl 

            call endl       ;output a new line
            ret             


    endp


    exit:
    mov ax, 4c00h               ;This is just a failsafe exit
    int 21h


END
.MODEL SMALL
.STACK 100h
.DATA

choice_msg  db 13,10,'Addition or Subtraction?',13,10,'$' 
first_msg   db 13,10,'Enter the first number:',13,10,'$'
second_msg  db 13,10,'Enter the second number:',13,10,'$'
result_msg  db 13,10,'The result is:',13,10,'$'
new_line    db 13,10,'$'
val1        db ?
num1        db ?
num2        db ?
num3        db ?        ; purely a buffer variable 
ten         db 10   
t1          db 0
t2          db 0     
result      db 0

.CODE                   ;where the code is written
start:  

    mov ax, @data           ;Moves the address of the variables under .DATA into ax
    mov ds,ax           ;moves ax into ds. the two lines allow you to display string using the 21h interrupt sequence 9

    mov ah,09
    mov dx, offset choice_msg
    int 21h             ;displays the string in choice_msg

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01

    cmp al,'+'          ;compares the entered value in with "+"
    jne subtraction         ;if the enterd value is "+" then it jumps to addition else it jumps to subtraction

addition: 

    call read           ;Read the input
    call endl           ;output new line

    mov bl, num2        ;move the value of num 2 into bl

    add num1,bl         ;adds num2 and num1 to form the sum1
    mov al, num1        ;mov num1 to al
    mov result, al      ;store the result of the sum in result

    call write          ;write the output 
    jmp exit

subtraction:

    call read           ;Read the input
    call endl           ;output new line

    mov bl, num2        ;move value of num2 to bl

    sub num1,bl         ;subtracts the value in num2 from the value in num1
    mov al, num1        ;move result to a register
    mov result, al      ;move the result of the subtraction to result

    call write          ;display result with write procedure
    jmp exit


    ;-----------------------
    ;procedure declarations: 

    proc endl

        mov ah,09
        mov dx, offset new_line
        int 21h             ;goes to next line, i.e. "enter"

        ret

    endp


    proc read


        mov ah,09
        mov dx, offset first_msg
        int 21h             ;displays the string in first_msg

        mov ah,01           ;read char
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the vaule in the al
        mov num1,al         ;moves the value in the al to the variable num1

        mov ah,01           ;read second char
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num2,al         ;moves the value in the al to the variable num2

        mov al,num1         ;moves the value in num1 into the al
        mul ten             ;multiplies the value in the al by ten
        add al,num2         ;adds the value in num2 to the al, to get the two-digit number
        mov num1,al         ;moves the two digit value into

        call endl

        mov ah,09
        mov dx, offset second_msg   ;displays the string in second_msg
        int 21h             

        mov ah,01
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num2,al         ;moves the new value in the al into the variable num2

        mov ah,01
        int 21h             ;copies a value into the al, using subfunction 01
        sub al,48           ;subtracts 48 from the value in the al
        mov num3,al         ;moves the new value in the al into the variable num3

        mov al,num2         ;moves the value in num2 into the al
        mul ten             ;multiplies the value in the al by ten
        add al,num3         ;adds the value in num3 to the al, to get a two-digit number
        mov num2,al         ;moves the value in the al into the variable num2

        ret                 ;first number in num1, second in num2    
    endp


    ;The write procedure writes the decimal stored in result.
    ;by dividing by ten it seperates the two digits as quotient
    ;and remainder. Then it outputs the quotient and remainder
    ;in ascii form.
    proc write
            mov dx,offset result_msg
            mov ah,09h
            int 21h         ;display the result_msg string

            mov al,result   ;move the result from add/sub to al
            mov ah,00       ;initialize ah
            div ten         ;div al by ten, quotient is in al 
                            ;remainder is stored in ah.

            mov dl,ah       ;move the remainder to dl
            mov t2,dl       ;store the remainder in t2

            mov dl,al       ;move quotient into dl
            add dl,48       ;add 48 to dl, to convert it to ascii
            mov ah,02h      ;char display interupt code
            int 21h         ;display char in dl register

            mov dl,t2       ;move remainder to t2
            add dl,48       ;convert it to ascii by adding 48
            mov ah,02h      ;display character in dl interupt code
            int 21h         ;diplays contents of dl 

            call endl       ;output a new line
            ret             


    endp


    exit:
    mov ax, 4c00h               ;This is just a failsafe exit
    int 21h


END