;--------------------------------------------------------
;加减乘除四则运算
;--------------------------------------------------------
;********************************************************
data segment
inbuff db 15,?,15 dup(?)
first dw ?
second dw ?
oper db ?
result dw ?
sign db ? ;结果的符号
result_str db 5 dup(?) ;结果的字符串形式
prompt db 'Input Expression :','$'
errmsg db 'Input Illegal!','$'
mess db 'Continue?(y/n):','$'
newline db 13,10,'$'
data ends
;********************************************************
code segment
;--------------------------------------------------------
main proc far
assume cs:code,ds:data
start:
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mainlop:
call input
call calculate
call print
lea dx,mess
mov ah,09h
int21h
mov ah,01h
int21h
cmp al,'n'
je mainret
call crlf
jmp mainlop
mainret:
ret
main endp
;--------------------------------------------------------
;输入表达式,并检查表达式是否合法,
;取出操作数和操作类型存入内存
input proc near
push ax
push dx
s1:
lea dx,prompt
mov ah,09h
int21h
;输入表达式
lea dx,inbuff
mov ah,0ah
int21h
;判断表达式是否合法
call check
cmp al,'n'
je error ;非法
call fetch ;取操作数和操作符
jmp inputret
error:
call crlf ;换行
lea dx,errmsg
mov ah,09h
int21h
call crlf
jmp s1
inputret:
pop dx
pop ax
ret
input endp
;--------------------------------------------------------
;对表达式进行合法性检查
;返回:
;* (al)='y'/'n''y'代表合法,'n'代表非法
check proc near
push bx
push cx
mov al,byteptr inbuff[1]
cmp al,0
je notpass
lea bx,inbuff
add bx,2
mov cx,0
part1:
mov al,byteptr [bx]
cmp al,'9'
ja notpass
cmp al,'0'
jb part11
add cx,1
inc bx
jmp part1
part11:
sub cx,0 ;判断第一个操作数是否最少有一位
jz notpass
mov cx,0 ;清零
part2:
cmp al,'+'
je part3
cmp al,'-'
je part3
cmp al,'*'
je part3
cmp al,'/'
je part3
jmp notpass
part3:
inc bx
mov al,byteptr [bx]
cmp al,'0'
jb notpass
cmp al,'9'
ja part31
add cx,1
jmp part3
part31:
sub cx,0 ;判断第二个操作数是否最少有一位
jz notpass
part4:
cmp al,'='
jne notpass
pass:
mov al,'y'
jmp checkret
notpass:
mov al,'n'
checkret:
pop cx
pop bx
ret
check endp
;--------------------------------------------------------
;取操作数和操作符(+-*/)
fetch proc near
push ax
push bx
push dx
push si
lea si,inbuff
add si,2
mov ax,0
mov dx,0
number1:
mov dl,byteptr [si]
cmp dl,'0'
jb operation
mov bx,10
mul bx
mov dl,byteptr [si]
sub dl,30h
add ax,dx
inc si
jmp number1
operation:
;保存第一个操作数
mov word ptr first,ax
;保存操作类型
mov byteptr oper,dl
inc si
mov ax,0
mov dx,0
number2:
mov dl,byteptr [si]
cmp dl,'9'
ja fetchret
sub dl,30h
mov bx,10
mul bx
mov dl,byteptr [si]
sub dl,30h
add ax,dx
inc si
jmp number2
fetchret:
;保存第二个操作数
mov word ptr second,ax
pop si
pop dx
pop bx
pop ax
ret
fetch endp
;--------------------------------------------------------
;计算表达式的值,结果存入result变量中
calculate proc near
push ax
push bx
push cx
push dx
mov byteptr sign,'+';初始符号位正
mov ax,word ptr first
mov cx,word ptr second
mov bl,byteptr oper
cmp bl,'+'
je addition
cmp bl,'-'
je subtract
cmp bl,'*'
je multi
jmp divide
addition:
add ax,cx
jmp save
subtract:
cmp ax,cx
jae sub1
jmp sub2
sub1:
sub ax,cx
jmp save
sub2:
sub cx,ax
mov ax,cx
mov byteptr sign,'-'
jmp save
multi:
mul cx
jmp save
divide:
mov dx,0
div cx
save:
mov word ptr result,ax
calret:
pop dx
pop cx
pop bx
pop ax
ret
calculate endp
;--------------------------------------------------------
;以十进制形式显示结果result的值
print proc near
push ax
push cx
push dx
push si
lea si,result_str
mov ax,result
mov cx,10000
call divdw
mov cx,1000
call divdw
mov cx,100
call divdw
mov cx,10
call divdw
mov cx,1
call divdw
;显示结果result_str
lea si,result_str
mov cx,5 ;5位数
;去掉前导0
printlop1:
mov al,byteptr [si]
cmp al,'0'
je cut0
jne printch
cut0: ;去掉0
dec cx
inc si
cmp cx,1
je printch
jmp printlop1
printch: ;打印字符
push cx
;置光标位置
mov bh,0
mov ah,3
int10h
mov dl,offset errmsg - offset prompt
dec dl
add dl,inbuff[1]
mov ah,2
int10h
pop cx
;输出符号位
mov dl,byteptr sign
cmp dl,'-'
jne printlop2
mov ah,02h
int21h
printlop2:
mov dl,byteptr [si]
mov ah,02h
int21h
inc si
loop printlop2
call crlf
printret:
pop si
pop dx
pop cx
pop ax
print endp
;--------------------------------------------------------
;执行除法并将商存放到result_str的相应位置
;参数:
;* (ax)=被除数
;* (cx)=除数
;返回:
;* (ax)=余数
divdw proc near
push dx
mov dx,0
div cx
;保存商
add al,30h
mov byteptr [si],al
inc si
mov ax,dx ;保存余数
pop dx
ret
divdw endp
;--------------------------------------------------------
;换行
crlf proc near
lea dx,newline
mov ah,09h
int21h
ret
crlf endp
;--------------------------------------------------------
code ends
;********************************************************
end start