问题描述
我正在编写一个简单的汇编计算器,但无论我做什么,我都无法让百分比部分开始正常工作
我几乎花了 2 天半的时间来研究它,看起来它不喜欢改变任何东西。 我尝试了乘法和除法、混合或单独的每一种组合,但我无法使它起作用。
.model small
.data
greating_msg db 0AH,0DH,"Welcome to Calculator $"
name_data db 0AH,"name : vahid ... $"
birthday_data db 0AH,"birthday : 1378/05/24 $"
instruction_msg db 0AH,"type simple equations to solve Examples : 1+1 or 5*8 : $",0AH," c"
error_msg db 10,"Exit due error$"
division_reminder_msg db " and remainder=$"
input db 3 DUP('0')
PRINTLINE macro str
LEA DX,str ;to print string
MOV AH,09H ;To display character string
INT 21H ;call DOS function
endm
.code
; printing greating_msg
mov dx,@data ;move offsets to data segment
mov ds,dx
PRINTLINE greating_msg
PRINTLINE name_data
PRINTLINE birthday_data
PRINTLINE instruction_msg
mov bx,0
take_input: ; loop to take input and print dl for each letter
mov ah,8 ; to input 1 character
int 21h
mov cl,al
cmp bx,1 ; if it's the second character then it's opreation
je check_cl_opreation
call check_cl_number
cmp al,1
je assign
jmp print_error_and_quit
check_cl_opreation: ; to check if the input operation is a supported one
cmp cl,'+'
je assign
cmp cl,'-'
je assign
cmp cl,'*'
je assign
cmp cl,'/'
je assign
cmp cl,']'
je assign
jmp print_error_and_quit
assign:
call print_cl
mov input[bx],cl
inc bx
cmp bx,3
jne take_input
calculate_input:
mov cl,input[0] ; First number
mov bl,input[1] ; the mark between the numbers
mov ch,input[2] ; Second number
cmp bl,'+'
je adding
cmp bl,'-'
je subtracting
cmp bl,'*'
je multiplying
cmp bl,'/'
je dividing
cmp bl,']'
je percentage
print_error_and_quit:
mov ah,9
mov dx,offset error_msg
int 21h ; '!' = 21h
quit: ; Quit the program
mov ah,'L' ; 'L' = 4Ch
int 21h
adding:
call print_equal_sign
sub ch,'0'
add cl,ch
mov ch,'0' ; ch will be used as 10's number
jmp check_and_print_cx
subtracting:
call print_equal_sign
sub ch,'0'
sub cl,ch
call check_cl_number
cmp al,1
je print_sub
mov bh,cl
mov cl,'-'
call print_cl
mov cl,':' ; ':' = '9'+1
sub bh,'0' ; make bh contains exact number
add bh,10 ; add 10 to get number in positive in next instruction
sub cl,bh ; remove bh from cl to get positive number in cl
print_sub:
call print_cl
jmp quit
multiplying:
call print_equal_sign
sub ch,'0'
mov al,ch
mul cl
mov cl,al
mov ch,ah
add cl,'0'
add ch,'0'
call check_and_print_cx
check_and_print_cx:
call check_cl_number
cmp al,1
je print_cx
inc ch
sub cl,10
jmp check_and_print_cx
print_cx:
cmp ch,'0'
je print_units
mov bh,cl ; using bh as temp
mov cl,ch
call print_cl
mov cl,bh
print_units:
call print_cl
jmp quit
dividing:
call print_equal_sign
sub cl,'0' ; to use the real value of cl not '0'+value
sub ch,'0' ; to use the real value of ch not '0'+value
mov ah,0 ; clear ah to use ax in division
mov al,cl
mov bl,ch
div bl
mov ch,ah
mov cl,al
add cl,'0'
call print_cl
mov ah,9
cmp ch,0
je quit_division
mov dx,offset division_reminder_msg
int 21h ; '!' = 21h
mov cl,ch
add cl,'0'
call print_cl
quit_division:
jmp quit
percentage:
call print_equal_sign
sub ch,100
mul cl
mov cl,'0'
call check_and_print_cx
print_equal_sign:
mov ah,2
mov dl,'='
int 21h
ret
print_cl:
mov ah,cl
int 21h
ret
check_cl_number: ; check if the CL is a number if so return 1 in AL else return 0 in AL
cmp cl,'0'
jb not_number
cmp cl,'9'
ja not_number
mov al,1
ret
not_number:
mov al,0
ret
lpt_port PROC ;//////////////////////////// lpt1 port procedure //////////////////////////;
MOV DX,0378H
MOV AL,birthday_data
OUT DX,AL
ENDP ;//////////////////////////// END of lpt1 port procedure //////////////////////////;
end
解决方法
您的百分比部分忘记除以第二个数字!
a ] b = a * 100 / b
对于第一个数字 (a) 小于第二个数字 (b) 的情况,否则您会得到一个 3 位数的结果 (100+ %)您的程序(还)不能输出。这立即排除了第二个数字中的零,这是所需除法所必需的。
percentage:
call print_equal_sign
sub cx,'00' ; From ASCII to digits : CL is 1st number,CH is 2nd number
mov al,100
mul cl ; e.g. 1 * 100 = 100 3 * 100 = 300
div ch ; e.g. 100 / 2 = 50 % 300 / 7 = 42 %
mov cl,al ; Quotient (AH is remainder)
mov ch,0
add cx,'00' ; Back to ASCII
jmp check_and_print_cx