带括号的四则运算 汇编

;作者:HelloMsg
;网址:http://www.cnblogs.com/wbb2109/
;邮箱:wangbb844918243@gmail.com 
;时间:2011.11.26
;带括号的四则运算
;算法:1.将键盘输入的计算式(中缀式)存入array1中sub8;
;      2.将中缀式转换为后缀式存入array2中,算法思想:
;         从左至右逐字(word)读取array1中的内容:
;         a.当当前字符为数字时,直接输出到array2;
;         b.当当前字符为"("时,将其压栈;
;         c.当当前字符为")"时,则弹出堆栈中最上的"("之前的所
;           有运算符并输出到array2,然后删除堆栈中的"(" ;
;         d.当当前字符为运算符时,则依次弹出堆栈中优先级大于
;           等于当前运算符的,存入array2.再将当前运算符压栈
;         c.当为"="时,弹出所有栈中的内容存入array2.
;       3.建立一个栈,然后从左至右扫描array2,每遇到操作数
;         就压入栈中,每遇到运算符号,就弹出栈顶的操作数,
;         完成相应的操作并把结果再压入栈中。最后的结果将保
;         留在栈顶。
;       4.输出结果
;提示:该程序只对输入操作数小于65280,每步运算结果小于65535的
;      计算式有效。并且都是正整数。
 
assume cs:code,ds:data,ss:stack
data segment
     array1 dw 100 dup(0)     ;存放中缀表达式
     array2 dw 100 dup(0)      ;存放后缀表达式
     ;operator '(','=','+','-','*','/',作者约定优先级别为0,0,1,1,2,2     
     
data ends

stack segment
     dw 100 dup(0)
stack ends

code segment
main proc far
     mov ax,data
     mov ds,ax
     mov ax,stack
     mov ss,ax
     mov sp,200 
     

     call sub8
     call sub9 
     call sub10 
     
     call sub11
  mov ah,0
  int 16h
main endp
;使运算符高八位为0ffh,以区别内存中的操作数和运算符。
;这就是为什么规定输入的操作数要小于65280 。
sub8 proc near      ;将计算式按中缀式存入array1中
     push ax
     push bx
     push dx
     lea di,array1
     xor cx,cx
aa2: mov ah,1
     int 21h
     
     
     cmp al,30h    ;判断若小于48,则为运算符
     
     jc aa5

          
     cmp al,3ah    ;判断若大于57,则为等于号
     jnc aa1
     add cx,cx        ;否则为0~9,将其由ascii转换为数值
     mov bx,cx
     add cx,cx
     add cx,cx
     add cx,bx
     and ax,0fh
     add cx,ax

     jmp aa2
aa3: mov [di],cx
     inc di
     inc di
     mov cx,0            ;将数值存入内存,并cx赋0,标记其以存入内存
      
aa4: mov ah,0ffh         ;通过高8位区别数字还是运算符
     mov [di],ax
     inc di
     inc di
     jmp aa2
aa5: cmp cx,0              ;判断前面输入的是不是数字
     jz aa4
     jmp aa3
aa6: mov [di],cx
     inc di
     inc di
     mov cx,0            
aa1: cmp cx,0           ;判断若在输入等号的前一位是数值
     jnz aa6            ;则存入内存
     mov ah,0ffh
     mov [di],ax
     pop dx
     pop bx
     pop ax
     ret                 ;返主
sub8 endp


sub9 proc near               ;中缀式转后缀式,存入array2
     sub cx,cx
     push ax
     push bx
     push dx
     mov ax,'='
     mov ah,0ffh
     push ax
     inc cx
     lea di,array1
     lea si,array2
     
     
bb1: mov ax,[di]
     inc di
     inc di
     cmp ah,0ffh           ;小于0ffh就为数字
     jnc bb2               ;大于0ffh就为运算符
     mov [si],ax
     inc si
     inc si
bb3: jmp bb1 
bb2: cmp al,'('
     jz bb4         ;若为“(”,则压入栈
     cmp al,')'      ;若为“)”,则弹出栈中最上的
     jz bb5               ;'('之前的所有运算符并输出到array2
     cmp al,'='         ;若为“=”,则弹出栈中的所有
     jz bb6
bb11:mov bp,sp
     cmp al,'+'
     jz bb7  
     cmp al,'-'
     jz bb7
     cmp al,'*'
     jz bb9
     cmp al,'/'
     jz bb9
bb4: push ax
     inc cx
     jmp bb1
 
bb5: pop ax
     dec cx
     cmp al,'('
     jz bb1
     ;cmp al,'='           
    ; jz bb6
     mov [si],ax
     inc si
     inc si
     jmp bb5

 
bb7: cmp byte ptr [bp],'+'
     jz bb12
bb8: cmp byte ptr [bp],'-'
     jz bb12
bb9: cmp byte ptr [bp],'*'
     jz bb12
bb10:cmp byte ptr [bp],'/'
     jz bb12
     jmp bb4
     
bb12: pop bx
      dec cx
     mov [si],bx
     inc si
     inc si
     jmp bb11
  
bb6: pop ax
     mov [si],ax
     inc si
     inc si
     loop bb6
     pop dx
     pop bx
     pop ax
     ret
sub9 endp
sub10 proc near
    push ax
    push bx
    push dx 
    
    lea si,array2
pp1:mov ax,[si]
    inc si
    inc si
    cmp ah,0ffh
    jz pp2
    push ax
    jmp pp1 
pp2:cmp al,'='
    jz pp7
    pop bx
    pop dx
    cmp al,'+'
    jz pp3
    cmp al,'-'
    jz pp4
    cmp al,'*'
    jz pp5
    cmp al,'/'
    jz pp6
    
    
pp3:add dx,bx
    push dx
    jmp pp1
pp4:sub dx,bx
    push dx 
    jmp pp1
pp5:mov ax,dx
    mul bx
    push ax          ;用的是16位乘法,高位放在dx里,
    jmp pp1          ;低位放在ax里,这里约定结果小于65535
pp6:mov ax,dx
    mov dx,0         ;因为16位(除数)除法,则高16位默认在dx里,
                     ;所以要将dx置零
    div bx           ;ax存商,dx存 余数
    push ax
    jmp pp1 
pp7:pop cx          
    pop dx
    pop bx
    pop ax
    ret                  ;返主
sub10 endp
sub11 proc near           ;将结果以十进制形式输出到屏幕
     push ax
     push bx
     push dx
     cmp cx,10000
     jnc a12
     cmp cx,1000
     jnc a4
     cmp cx,100
     jnc a6
     cmp cx,10
     jnc a8
     jmp a10
a12:mov dl,-1
a3: sub cx,10000
     inc dl
     jnc a3
     add cx,10000
     or dl,30h
     mov ah,2
     int 21h
a4: mov dl,-1
a5: sub cx,1000
     inc dl
     jnc a5
     add cx,1000
     or dl,30h
     mov ah,2
     int 21h
a6: mov dl,-1
a7: sub cx,100
     inc dl
     jnc a7
     add cx,100
     or dl,30h
     mov ah,2
     int 21h
a8: mov dl,-1
a9: sub cx,10
     inc dl
     jnc a9
     add cx,10
     or dl,30h
     mov ah,2
     int 21h
a10:mov dl,cl
     or dl,30h
     mov ah,2
     int 21h
     pop dx
     pop bx
     pop ax
     ret                ;返主
sub11 endp

code ends
end main


欢迎访问我的bolg:http://www.cnblogs.com/wbb2109

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值