繁体   English   中英

在x86 Assembly(TASM)中添加或减去两个数字

[英]Adding or Subtracting two numbers in x86 Assembly (TASM)

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

.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 ?    
num2        db ?    
num3        db ?    
num4        db ?      
ten         db 10    

.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
    mov val1,al         ;moves the value in the al to the variable val1

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

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

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 01
    sub al,48           ;subtracts 48 from the vaule in the al
    mov num2,al         ;moves the value in the al to 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 value in the al to 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 the two-digit number
    mov num2,al         ;moves the two digit value into

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

    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 num3,al         ;moves the new value in the al into the variable num3

    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 num4,al         ;moves the new value in the al into the variable num4

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

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

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

    ; mov the value of num 3 into bl
    mov bl, num3

    add num2,bl         ;adds num3 and num2 to form the sum
    add num2,48         ;adds 48 to num2


    mov al,num2
    mov ah,02
    mov dl, al
    int 21h             ;displays the value that was in the al

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

    mov ax,4c00h
    int 21h             ;ends the program


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

    mov ah,01
    int 21h             ;copies a value into the al, using subfunction 001
    sub al,48           ;subtracts 48 from the value in the al
    mov num2,al         ;moves the 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 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

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

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

    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 value in the al into the variable num3

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

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

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

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

    mov bl, num3        ;move value of num3 to bl

    sub num2,bl         ;subtracts the value in num3 from the value in num2
    add num2,48         ;adds 48 to the new value in num2
    mov al,num2         ;moves the value in num2 into the al
    mov ah,02
    mov dh,al
    int 21h             ;displays the resulting value

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

    mov ax,4c00h
    int 21h             ;ends the program

END

这是一个过程(使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM