[8086]读取并计算算数表达式

本文介绍了一个使用emu8086工具的汇编程序,该程序能够解析并计算用户输入的整数加减运算表达式,支持括号和负数,确保了计算结果在-32768至32767范围内。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工具: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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值