⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jisq.asm

📁 用汇编编写了一个运算器
💻 ASM
字号:
title ji suan qi
sseg segment	;define stack segment
	dw 128 dup(0)
        tos label word
sseg ends
;---------------------------------------------------------------------------------
dseg segment	;define data segment
        new db "press 'Esc' to exit,else continul",0dh,0ah,'$'
	ychu db "the number is too lager,please input again",0dh,0ah,'$'
        err  db"biao da shi ge shi bu zhen que,qing cong xin shu ru",0dh,0ah,'$'
;---------------------------------------------------------------------------------------------------	
;存储各运算符间的优先级比较,‘'’为堆栈初始化时压入栈底的符号起标志作用
   ad  db ">><<<a<a<"   ;加同堆栈中的‘'’,左括号,右括号,乘,加,减,除的优先级比较
   su  db ">><<<a<a<"   ;减同堆栈中的‘'’,左括号,右括号,乘,加,减,除的优先级比较
   mu db">><<>a>a<"    ;乘同堆栈中的‘'’,左括号,右括号,乘,加,减,除的优先级比较
   divv db">><<>a>a<"   ;除同堆栈中的‘'’,左括号,右括号,乘,加,减,除的优先级比较
   lk   db ">>a>>a>a>"    ;左括同堆栈中‘'’,的左括号,右括号,乘,加,减,除的优先级比较
   rk   db ">=<<<a<a<"    ;右括同堆栈中‘'’,的左括号,右括号,乘,加,减,除的优先级比较
   equa  db "=<<<<a<a<"    ;等号同堆栈中‘'’,的左括号,右括号,乘,加,减,除的优先级比较
dseg ends
;----------------------------------------------------------------------------------
cseg segment 	;define code segment
	assume cs:cseg,ds:dseg,ss:sseg
start:mov ax,dseg
	mov ds,ax
	mov ax,sseg
	mov ss,ax	
        mov dx,offset new
        mov ah,09h
        int 21h
;--------------------------------------------------------------------------------
next:mov sp,offset tos	;setup sp
        mov dl,39         ;将’'‘压入栈底,起标志作用
	mov dh,0
	push dx
	mov ch,1                 ;标志上次读入的字符是数字(0),还是字符(1),或是右括号(3)
	mov cl,0                   ;用来记录括号,输入左括加1,右括减1
	mov bx,0
;-----------------------------------------------------------------------------------
again: mov ah,01h
           int 21h
	   cmp al,1bh
	   jz jover                ;按esc键退出程序
           cmp al,'0'
	   jb oprt
	   cmp al,'9'
	   ja jequal
	   jmp opnd
jover:jmp over
jequal:jmp equal
;----------------------------------------------------
;当输入的字符是操作数时
opnd: cmp ch,3           ;判断上一次输入的运算符是不是右括号,是则跳到error
           jz jerror
	   cmp ch,1
	   jnz opnd1
	   mov bx,0
opnd1:sub al,30h
           mov ch,al
	   mov dh,0
           mov ax,bx
	   mov bx,0ah
	   mul bx
	   jb jyichu             ;操作数大于655235益处
	   mov bx,ax
	   mov ah,0
	   mov al,ch
	   add bx,ax
	   jb jyichu         ;-------
	   mov ch,0
	   jmp again
jerror: jmp error
jyichu:jmp yichu
;------------------------------------------------------
;当输入字符是运算符时
oprt: mov ah,0            
        cmp ch,1            ;当上次读入的字符为运算符(不包括右括号)时,
        jnz xz                  ;判断当前读入的运算符是不是左括号,不是则跳到error
        cmp al,'('
        jnz  jerror
        inc cl                ;记录左括号
	push ax                ;左括号优先级最高,直接压栈
	jmp again
xz:    cmp al,'+'            ;上次读入字符为数字或右括号,当前读入的运算符必须为
          jz jia1                  ;‘+’,‘-’,‘*’,‘/’,‘)’,否则表达式错误,跳到error
	  cmp al,'-'
	  jz jian1
	  cmp al,'*'
	  jz cheng1
	  cmp al,'/'
	  jz chu1
	  cmp al,')'
	  jz youkuo1
	  jmp error
jia1:  mov si,offset ad
         jmp bijiao
jian1:mov si,offset su
         jmp bijiao
cheng1:mov si,offset mu
             jmp bijiao
chu1:   mov si,offset divv
             jmp bijiao
youkuo1:dec cl
              cmp cl,0h
	      js jerror           ;右括号在左括号出现之前出现,转移
             mov si,offset rk
             jmp bijiao
bijiao:pop dx  
         mov ch,dl
          sub dx,39d
         add si,dx
         cmp byte ptr[si],'>'
         jz yazhan
	 cmp byte ptr[si],'='          
	 jz tuokuo           ;栈中最近的符号为左括号,当前读入为右括号,去括号
jisuan:sub si,dx      ;将si还原到起始位置
         cmp ch,'+'      
         jz jia2
         cmp ch,'-'
	 jz jian2
	 cmp ch,'*'
	 jz cheng2
	 cmp ch,'/'
	 jz chu2
	 ;栈中最近的运算符为左括号的情况是[si]不可能是’<‘
	 ;ch为右括号的情况不存在,因为右括号是不可能被压入栈的

tuokuo:cmp al,'='                   ;优先级相同有两种情况:左括号同右括号,‘'‘同’=‘
             jz outresult                 ;如是第二种情况,跳到outresult,第一种则脱括号
             mov ch,3
	     jmp again
yazhan:mov dh,0
             mov dl,ch
	     push dx
	     push bx
             mov ah,0
	     push ax
             mov ch,1
             jmp again
jia2: pop dx
       add bx,dx
       jo yichu         ;???????????????yichu 
       jmp bijiao
jian2:pop dx
       sub dx,bx
       jo yichu     ;??????????????????
       mov bx,dx
       jmp bijiao
 cheng2:pop dx
             mov ch,al
             mov ax,dx
             imul bx
             jo yichu     ;????????????
             mov bx,ax
             mov al,ch
             jmp bijiao
chu2:pop dx
      mov ch,al
      mov ax,dx
      mov dx,0
      idiv bx
      mov bx,ax
      mov al,ch
      jmp bijiao
;------------------------------------------------------
equal:cmp al,'='
          jnz error
	  cmp cl,0
	  jnz error        ;判断左括号和右括号是否成对出现
          mov si,offset equa
	  jmp bijiao
;---------------------------------------------------------------------------
outresult:mov dx,'a'
                push dx
                cmp bx,0
                js fushu
go:		mov dx,0
		mov ax,bx
		mov cx,0ah
		div cx
                add dl,30h
		mov dh,0
		push dx
		mov bx,ax
		cmp bx,0
		jnz go
go1:         pop dx
		cmp dl,'a'
		jz go2
		mov ah,2
		int 21h
		jmp go1
go2:	       call newline                      ;
               mov dx,offset new
               mov ah,09h
               int 21h
	       jmp next
fushu:mov dl,'-'
          mov ah,02
	  int 21h
	  neg bx
	  jmp go
;--------------------------------------------------------
yichu:call newline
          mov dx,offset ychu
          mov ah,09h
	  int 21h
	  jmp next
;--------------------------------------------------------
error:call newline
         mov dx,offset err
         mov ah,09h
	 int 21h
	 jmp next
;--------------------------------------------------------
over: mov ah,4ch
          int 21h
;----------------------------------------------------------
newline proc
	push dx
	push ax
	mov dl,0dh
	mov ah,2
	int 21h
	mov dl,0ah
	mov ah,2
	int 21h
	pop ax
	pop dx
	ret
newline endp
;--------------------------------------------------------
cseg ends
	end start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -