📄 arith2.asm
字号:
;******************************************************
;* 文件名:Arith2.asm
;* 创建日期:2001.7.1
;* 作者:陈文尧
;* 功能:计算数学表达式,比如:12*(1+2*4)^(30-5^2)/21
;* 备注:本程序是Arith.asm的修订版本,因为后者有几点毛病:
;* 1.只要括号成对,空的括号也认为合法,
;* 比如(())1+2(((())))*3合法
;* 2.数据和符号各自独立,只要各自顺序对就认为合法,
;* 比如100 25 84+(-)*2居然等同于100+(25-84)*2
;* 3.输入负数出错,比如-100*(-20)倒是错的
;* 4.括号前不能添加负号,比如-(2+3)*5会出错
;******************************************************
include system.inc
include stdio.inc
include stack.inc
;******************************************************
;* 以下代码由汇编专家产生,不要随便修改
;******************************************************
.CODE
ifdef __COM__
org 100h
endif
@@Start:
;------------------------------------------------------
; 初始化数据段
;------------------------------------------------------
InitDS cs
;------------------------------------------------------
; 释放多余内存
;------------------------------------------------------
ModifyMemory ;xxx
;------------------------------------------------------
; 调用主函数
;------------------------------------------------------
call main
;------------------------------------------------------
; 正常返回DOS
;------------------------------------------------------
@@Exit:
ReturnDos
;++++++++++++++++++++++++++++++++++++++++++++++++++++++
;+ 主函数,加入实现程序功能的代码
;++++++++++++++++++++++++++++++++++++++++++++++++++++++
main proc
CreateStack <offset opStk>,01h
CreateStack <offset opnStk>,04h
mov al,0ah
mov opBuffer,al
StackPush <offset opStk>,<offset opBuffer>
sub bp,bp
Puts <offset msg1>
GetChar
mov bl,al
@Begin:
call Judge
cmp al,01h
jz short @Case1
cmp al,02h
jz short @Case2
cmp al,03h
jz short @Case3
jmp Error
@Case3:
GetChar
mov bl,al
jmp @Begin
@Case2:
or bp,bp
jz short @Cask2@Skip
call Error
@Cask2@Skip:
inc bp
sub esi,esi
@Case2@Begin:
imul edi,esi,0ah
mov esi,ebx
and esi,000000ffh
sub esi,'0'
add esi,edi
GetChar
mov bl,al
call Judge
cmp al,02h
jz @Case2@Begin
mov opnBuffer,esi
StackPush <offset opnStk>,<offset opnBuffer>
jmp @Begin
@Case1:
StackTop <offset opStk>,<offset opBuffer>
mov bh,opBuffer
or bp,bp
jnz short @Case1@Skip
call f2
call g2
cmp al,ah
jb short @Case1@b
ja short @Case1@a
call Error
@Case1@a:
cmp al,02h
jnz short @Case1@Skip
sub eax,eax
inc eax
cmp bl,'+'
jz short @Case1@Positive
cmp bl,'-'
jz short @Case1@Negative
call Error
@Case1@b:
cmp ah,02h
jnz short @Case1@Skip
call Error
@Case1@Negative:
neg eax
@Case1@Positive:
mov opnBuffer,eax
StackPush <offset opnStk>,<offset opnBuffer>
mov opBuffer,'*'
StackPush <offset opStk>,<offset opBuffer>
GetChar
mov bl,al
jmp @Begin
@Case1@Skip:
call f
call g
cmp al,ah
jb short @b
ja short @a
StackPop <offset opStk>,<offset opBuffer>
cmp opBuffer,0ah
jz short @End
GetChar
mov bl,al
jmp @Begin
@a:
mov opBuffer,bl
StackPush <offset opStk>,<offset opBuffer>
GetChar
mov bl,al
sub bp,bp
jmp @Begin
@b:
StackPop <offset opStk>,<offset opBuffer>
StackLength <offset opnStk>
cmp ax,0002h
jnl short @Skip
mov bl,opBuffer
jmp short Error
@Skip:
StackPop <offset opnStk>,<offset opnBuffer>
mov esi,opnBuffer
StackPop <offset opnStk>,<offset opnBuffer>
mov edi,opnBuffer
call Operation
mov opnBuffer,edi
StackPush <offset opnStk>,<offset opnBuffer>
jmp @Begin
@End:
StackLength <offset opnStk>
cmp ax,0001h
jnz short Error
Puts <offset msg3>
StackPop <offset opnStk>,<offset opnBuffer>
PutLong <word ptr opnBuffer+02h>,<word ptr opnBuffer>
;
@Return:
ret
main endp
Error proc near
Puts <offset msg2>
PutChar bx
ClearStack <offset opnStk>
ClearStack <offset opStk>
mov ax,4c01h
int 21h
Error endp
Judge proc near
cmp bl,'+'
jz short @Judge1
cmp bl,'-'
jz short @Judge1
cmp bl,'*'
jz short @Judge1
cmp bl,'/'
jz short @Judge1
cmp bl,'^'
jz short @Judge1
cmp bl,0ah
jz short @Judge1
cmp bl,'('
jz short @Judge1
cmp bl,')'
jz short @Judge1
cmp bl,'0'
jb short @NextJudge
cmp bl,'9'
ja short @NextJudge
mov al,02h
ret
@NextJudge:
cmp bl,' '
jz short @Judge3
cmp bl,09h
jz short @Judge3
mov al,00h
ret
@Judge1:
mov al,01h
ret
@Judge3:
mov al,03h
ret
Judge endp
f proc near
cmp bh,'+'
jz short @f4
cmp bh,'-'
jz short @f4
cmp bh,'*'
jz short @f6
cmp bh,'/'
jz short @f6
cmp bh,'('
jz short @f2
cmp bh,')'
jz short @f9
cmp bh,'^'
jz short @f6
mov ah,01h
ret
@f2:
mov ah,02h
ret
@f4:
mov ah,04h
ret
@f6:
mov ah,06h
ret
@f9:
mov ah,09h
ret
f endp
g proc near
cmp bl,'+'
jz short @g3
cmp bl,'-'
jz short @g3
cmp bl,'*'
jz short @g5
cmp bl,'/'
jz short @g5
cmp bl,'('
jz short @g8
cmp bl,')'
jz short @g2
cmp bl,'^'
jz short @g8
mov al,01h
ret
@g2:
mov al,02h
ret
@g3:
mov al,03h
ret
@g5:
mov al,05h
ret
@g8:
mov al,08h
ret
g endp
f2 proc near
cmp bh,'+'
jz short @f2@2
cmp bh,'-'
jz short @f2@2
cmp bh,'*'
jz short @f2@2
cmp bh,'/'
jz short @f2@2
cmp bh,')'
jz short @f2@3
cmp bh,'^'
jz short @f2@2
mov ah,01h
ret
@f2@2:
mov ah,02h
ret
@f2@3:
mov ah,03h
ret
f2 endp
g2 proc near
cmp bl,'+'
jz short @g2@2
cmp bl,'-'
jz short @g2@2
cmp bl,'*'
jz short @g2@2
cmp bl,'/'
jz short @g2@2
cmp bl,'('
jz short @g2@3
cmp bl,'^'
jz short @g2@2
mov al,01h
ret
@g2@2:
mov al,02h
ret
@g2@3:
mov al,03h
ret
g2 endp
Operation proc near
mov al,opBuffer
cmp al,'+'
jz short @Add
cmp al,'-'
jz short @Sub
cmp al,'*'
jz short @Mul
cmp al,'/'
jz short @Div
cmp al,'^'
jz short @Pow
jmp Error
@Pow:
mov ecx,esi
sub eax,eax
inc eax
jcxz short @Skip2
@PowNext:
imul edi
loop @PowNext
@Skip2:
mov edi,eax
ret
@Add:
add edi,esi
ret
@Sub:
sub edi,esi
ret
@Mul:
mov eax,edi
imul esi
mov edi,eax
ret
@Div:
mov eax,edi
sub edx,edx
idiv esi
mov edi,eax
ret
Operation endp
msg1 db '请输入数学表达式:',00h
msg2 db '输入错误:',00h
msg3 db '计算结果:',00h
opBuffer db ?
opnBuffer dd ?
opStk FSTACK <>
opnStk FSTACK <>
;******************************************************
;* 标志程序结束并指定程序入口
;******************************************************
end @@Start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -