工具:emu8086
要求:编程计算任一整数加减运算表达式,其中表达式长度不超过256个字节,从键盘输入,可带括号。测试保证操作数和计算结果范围为-32768~32767,不包含不必要的括号。一些测试样例如下:
1+1
-2+1
2-(-1)
1-(-2+3)
-10000+2
; you may customize this and other start-up templates;
; the location of this template is c:\emu8086\inc\0_com_template.txt
data segment
expression dw 100 dup (-1);
data ends
code segment
assume ds:data, cs:code
start:
mov ax, data
mov ds, ax
mov es, ax
;获得输入并且存储
push 0 ;哨兵
lea di,expression
mov dx,0 ;暂存数字
mov ah,1
mov bx,0 ;flag,记录前一个输入类型,主要用于负数的处理
;读到-时候,前一个为数字,就是减号
;否则只能为(,这时为负号
int 21h
enterloop:
cmp al,13 ;回车,结束
je enterloopend
cmp al,40 ;(
je opsolve1
cmp al,41 ;)
je opsolve2
cmp al,43 ;+
je opsolve4
cmp al,45 ;-
je opsolve3
numsolve:
;都不是,则处理数字
loopforanum:
mov cl,al
mov ax,10
mul dx
mov dx,ax
sub cl,30h
mov ch,0
add dx,cx
mov ah,1
int 21h
cmp al,40 ;(
je notnum
cmp al,41 ;)
je notnum
cmp al,43 ;+
je notnum
cmp al,45 ;-
je notnum
cmp al,13 ;换行
je notnum
jmp loopforanum
notnum:
mov [di],dx
add di,2
mov dx,0 ;存数字,清零
mov bx,1
jmp enterloop
opsolve1: ;(
mov ah,0
push ax
mov bx,0
mov ah,1
int 21h
jmp enterloop
opsolve2: ;)
pushoploop: ;提符号
pop ax
cmp ax,40
je return
mov [di],ax
add di,2
jmp pushoploop
return:
mov bx,0
mov ah,1
int 21h
jmp enterloop
opsolve3: ; -
cmp bx,1 ;非负号
je bigger
mov cx,0
mov [di],cx
add di,2
bigger:
pop cx
cmp cx,43 ;+
je next3
cmp cx,45 ;-
je next3
push cx ;左括号压回去
jmp next4
next3:
mov [di],cx
add di,2
next4:
mov ah,0
push ax
mov bx,0
mov ah,1
int 21h
jmp enterloop
opsolve4:
pop cx
cmp cx,43 ;+
je next1
cmp cx,45 ;-
je next1
push cx ;左括号压回去
jmp next2
next1:
mov [di],cx
add di,2
next2:
mov ah,0
push ax
mov bx,0
mov ah,1
int 21h
jmp enterloop
enterloopend:
;先把栈中的符号存好
pushoploopextra: ;提符号
pop ax
cmp ax,0
je leave
mov [di],ax
add di,2
jmp pushoploopextra
leave:
;得到一个后缀表达式存放在expression中,下面进行运算
mov si,di ;si作为记录
lea di,expression
computeloop: ;怎么区别算符和数字,暂不考虑重叠(做标记区分,或者是计算的时候再计算数值)
cmp di,si
je endofall
mov cx,[di]
add di,2
cmp cx,43 ;+
je addfunc
cmp cx,45 ;-
je subfunc
push cx
jmp computeloop
addfunc:
pop bx
pop cx
add cx,bx
push cx
jmp computeloop
subfunc:
pop bx
pop cx
sub cx,bx
push cx
jmp computeloop
endofall:
;输出
mov dl, 0dh ;回车
mov ah, 2
int 21h
mov dl, 0ah ;换行
int 21h
cmp cx,0 ;判断结果正负
jg zheng
mov dl,45
mov ah, 2
int 21h
mov bx,0
sub bx,cx
mov cx,bx
zheng:
mov bx,0 ;高位0标记
mov ax, cx
mov dx, 0 ;令高位为0
mov cx, 10000
div cx
push dx
mov dx, ax
add dx, 30h ;转化成ascii码
mov ah, 2 ;设置 int输出dl中字符
cmp bx,0
ja not01
cmp dl, 30h
jz zero1 ;万位为0则不输出
not01:
int 21h ;输出万位
mov bx,1
zero1:
pop dx
mov ax,dx ;余数放在ax中
mov dx, 0 ;令高位为0
mov cx, 1000
div cx
push dx
mov dx, ax
add dx, 30h ;转化成ascii码
mov ah, 2 ;设置int输出dl中字符
cmp bx,0
ja not02
cmp dl, 30h
jz zero2 ;千位为0则不输出
not02:
int 21h ;输出千位
mov bx,1
zero2:
pop dx
mov ax,dx ;余数放在ax中
mov dx, 0 ;令高位为0
mov cx, 100
div cx
push dx
mov dx, ax
add dx, 30h ;转化成ascii码
mov ah, 2 ;设置int输出dl中字符
cmp bx,0
ja not03
cmp dl, 30h
jz zero3 ;百位为0则不输出
not03:
int 21h ;输出百位
mov bx,1
zero3:
pop dx
mov ax,dx ;余数放在ax中
mov dx, 0 ;令高位为0
mov cx, 10
div cx
push dx
mov dx, ax
add dx, 30h ;转化成ascii码
mov ah, 2 ;设置int输出dl中字符
cmp bx,0
ja not04
cmp dl, 30h
jz zero4 ;十位为0则不输出
not04:
int 21h ;输出十位
mov bx,1
zero4:
pop dx
mov ax,dx ;余数放在ax中
mov dx, 0 ;令高位为0
mov cx, 1
div cx
mov dx, ax
add dx, 30h ;转化成ascii码
mov ah, 2 ;设置int输出dl中字符
cmp dl, 30h
int 21h ;输出个位
;程序结束,返回到操作系统系统
mov ax, 4c00h
int 21h
end start
code ends
ret