计算器中的 emu 8086 除法错误溢出

问题描述

我正在用汇编编写一个简单的计算器,但无论我做什么,我都无法让百分比部分开始正常工作并始终出现此错误

除法错误 - 溢出。

我几乎为它工作了一天半,看起来它不喜欢改变任何东西。
我尝试了乘法和除法、混合或单独的每一种组合,但我无法使它起作用。

org 100h

jmp start       ; jump over data declaration
hello db 0AH,0DH,"===========Calculator program assembly==========$"   
my_name db  0AH,"========= behnam abbas abbadi =========$"   
birthday db  0AH,"========= 1378/05/24 ========= $" 
msg:    db    0AH,"1-Add",0dh,0ah,"2-Multiply","3-Subtract","4-Divide","5-Percentage",0Dh,0Ah,'$'
msg2:    db      0dh,"Enter First No : $"
msg3:    db      0dh,"Enter Second No : $"
msg4:    db      0dh,"Choice Error $" 
msg5:    db      0dh,"Result : $" 
msg6:    db      0dh,'thank you for using the calculator! press any key... ','$'
 
input_message_and_function  macro
            mov ah,09h  ;then let us handle the case of addition operation
            mov dx,offset msg2  ;first we will display this message enter first no also using int 21h
            int 21h
            mov cx,0 ;we will call InputNo to handle our input as we will take each number seprately  
            call InputNo  ;first we will move to cx 0 because we will increment on it later in InputNo
            push dx
            mov ah,9
            mov dx,offset msg3
            int 21h 
            mov cx,0
            call InputNo
endm 

      
info_print macro str     
     mov dx,offset str
     mov ah,09h
     int 21h
endm        

print_anser_and_exit macro
      push dx 
            mov ah,offset msg5
            int 21h
            mov cx,10000
            pop dx
            call View 
            jmp exit 
endm
    
start:    
info_print hello  
info_print my_name
info_print birthday
         mov ah,9
        mov dx,offset msg ;first we will display hte first message from which he can choose the operation using int 21h
        int 21h
        mov ah,0                       
        int 16h  ;then we will use int 16h to read a key press,to kNow the operation he choosed
        cmp al,31h ;the keypress will be stored in al so,we will comapre to 1 addition ..........
        je Addition
        cmp al,32h
        je Multiply
        cmp al,33h
        je Subtract
        cmp al,34h  
        je Divide   
        cmp al,35h
        je Percentage    
        call calc
        mov ah,09h
        mov dx,offset msg4
        int 21h
        mov ah,0
        int 16h
        jmp start      
        
 calc proc           ;////////////////////////////////// start calculation procedure ///////////////////////////////////////////////////
        
Addition:  
            input_message_and_function
        
            pop bx
            add dx,bx
            
            print_anser_and_exit
            
                       
Multiply:  
            input_message_and_function
            pop bx
            mov ax,dx
            mul bx 
            mov dx,ax          
            
           print_anser_and_exit


Subtract:
            input_message_and_function
            pop bx
            sub bx,dx
            mov dx,bx           
            
            print_anser_and_exit
    
            
Divide:  
            input_message_and_function
            pop bx
            mov ax,bx
            mov cx,0
            mov bx,0
            div cx
            mov bx,ax
            push bx 
            
            print_anser_and_exit


             
Percentage:
            input_message_and_function
       ;     pop bx
        ;    mov ax,100
         ;   mul bx 
          ;  mov dx,ax     
             pop bx
             mov ax,100
             mul ax
             mov bx,ax
             mov cx,dx
             mov dx,0
             mov bx,0 
             
             div cx
             mov bx,ax
             push bx 
            print_anser_and_exit
                  
endp                     ;////////////////////////////////// end calculation procedure ///////////////////////////////////////////////////
                                                                                                                                          
func proc                 ;////////////////////////////////// start functions procedure ///////////////////////////////////////////////////          
InputNo:    mov ah,0                                            

            int 16h ;then we will use int 16h to read a key press     
            mov dx,0  
            mov bx,1 
            cmp al,0dh ;the keypress will be stored in al so,we will comapre to  0d which represent the enter key,to kNow wheter he finished entering the number or not 
            je FormNo ;if it's the enter key then this mean we already have our number stored in the stack,so we will return it back using FormNo
            sub ax,30h ;we will subtract 30 from the the value of ax to convert the value of key press from ascii to decimal
            call ViewNo ;then call ViewNo to view the key we pressed on the screen
            mov ah,0 ;we will mov 0 to ah before we push ax to the stack bec we only need the value in al
            push ax  ;push the contents of ax to the stack
            inc cx   ;we will add 1 to cx as this represent the counter for the number of digit
            jmp InputNo ;then we will jump back to input number to either take another number or press enter          
   

;we took each number separatly so we need to form our number and store in one bit for example if our number 235
FormNo:     pop ax  
            push dx      
            mul bx
            pop dx
            add dx,ax
            mov ax,bx       
            mov bx,10
            push dx
            mul bx
            pop dx
            mov bx,ax
            dec cx
            cmp cx,0
            jne FormNo
            ret   


       
       
View:  mov ax,dx
       mov dx,0
       div cx 
       call ViewNo
       mov bx,dx 
       mov dx,0
       mov ax,cx 
       mov cx,10
       div cx
       mov dx,bx 
       mov cx,ax
       cmp ax,0
       jne View
       ret


ViewNo:    push ax ;we will push ax and dx to the stack because we will change there values while viewing then we will pop them back from
           push dx ;the stack we will do these so,we don't affect their contents
           mov dx,ax ;we will mov the value to dx as interrupt 21h expect that the output is stored in it
           add dl,30h ;add 30 to its value to convert it back to ascii
           mov ah,2
           int 21h
           pop dx  
           pop ax
           ret
      
   
exit:   mov dx,offset msg6
        mov ah,09h
        int 21h  
        mov ah,0    
        
        MOV DX,0378H
        MOV AL,birthday
        OUT DX,AL    

        int 16h
        ret                                                                  
        
endp   ;////////////////////////////////// end functions procedure ///////////////////////////////////////////////////

解决方法

Percentage:
        input_message_and_function
        pop bx
        mov ax,100
        mul ax
        mov bx,ax
        mov cx,dx      <<<<< DX=0 here!
        mov dx,0
        mov bx,0 
     
        div cx
        mov bx,dx
        mov dx,ax
        push bx 
        print_anser_and_exit

input_message_and_function 将第一个数字留在堆栈中,将第二个数字留在 DX 中。

mul ax 立即销毁第二个数字!
你为什么还要计算 100^2?只是mov ax,10000如果这是您需要的。

获取百分比

例如第一个输入是 80,第二个输入是 200,产生 40%

pop bx        ; 1st number is 80
mov cx,dx    ; 2nd number is 200
mov ax,100
mul bx        ; 80 * 100 = 8000
div cx        ; 8000 / 200 = 40
mov dx,ax