data segment
X DW ? ;存储输入数值,计算结果也存在此变量中
Y DW ? ;存储第2个数值
o db 0 ;o, p存储计算符号'+','-','*','/'
p db 0 ;p是存储前一个计算符号,o是第本次输入数值时的符号
data ends
code segment
assume cs:code, ds:data
start:
MOV AX, data
mov ds, ax
mov es, ax
lea si, X ;[si]用于存储输入的数值
call readint ;调用输入数值函数,此处调用,读取第1个数
N1:
cmp o, '=' ;比较,本次输入的运算符号是不是=,
jz r1 ;=,则表示本次运算结束
mov al, o ;不是的话,保存到p中,
mov p, al ;等第2个数输入后进行运算
mov Y, 0 ;Y置0,等待下一次输入
lea si, Y ;读取
call readint ;第2个数值
cmp p, '+' ;前一次输入的运算符,+,-,*,/分支
jz A1
cmp p, '-'
jz S1
cmp p, '*'
jz M1
cmp p, '/'
jz D1
jmp exit
A1:
mov ax, X ;进行加法运算
add ax, Y
mov X, ax ;运算结果放入X中
jmp N1
S1: ;减法运算
mov ax, X
sub ax, Y
mov X, ax
jmp N1
M1: ;乘法运算
mov ax, X
xor dx, dx
mov bx, Y
mul bx
mov X, AX
jmp N1
D1: ;除法运算
mov ax, X
xor dx, dx
mov bx, Y
div bx
mov X, ax
jmp N1
R1: ;运算结束,打印结果
mov ax, X
call print
exit:
mov ah,4ch
int 21h
;read a integer less than 65535
;return it in [si]
;and operator in o (variable)
readint proc near ;按10进制,读取数值函数
mov bx,10 ;10进制,基数
read:
mov ah,1 ;21h中断的1号子功能,读取一个字符
int 21h ;这里不考虑输入非数字情况
cmp al,'+' ;判断是不是 +, -, *, /, =符号
jz r0 ;是,则本次读取数值完毕
cmp al,'-'
jz r0
cmp al,'*'
jz r0
cmp al,'/'
jz r0
cmp al,'='
jz r0
and al,0Fh ; ;将ASCII码转成对应数值
mov ah,0 ;
xchg ax,[si] ;与[si]交换
mul bl ;上次读入的数值*10,
xchg [si],ax ;交换回[si]
add [si],ax ;再加上本次读取的数值
jmp read ;读下一个数字
r0:
mov o, al ;运算符号放入o变量中
ret
readint endp
;print value in ax with base 10
print proc near ;按10进制打印输出
mov bx, 10 ; base 10
xor cx,cx ; cx -> 0
Q0:
xor dx,dx ;除法是DX:AX 表示的数,除以bx
div bx
xor dx,0E30h ;dx中是余数,dl xor 30h,变成ASCII码值
push dx ;dh xor 0eh,是准备调用10h,0e是输出一个字符
inc cx ;有余数,则计算器+1
cmp ax, 0 ;商是否为0,=0时,表示本次除完
jnz Q0
Q1:
pop ax ; 循环打印输出到屏幕
int 10h ;
loop Q1
ret
print endp
code ends
end start
计算器这个题目用汇编本身就有难度了,还要加注释,更增工作量,难有人做呀。