📄 jisq.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 + -