www.pudn.com > Demo_asm_80x86.rar > 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,01h CreateStack ,04h mov al,0ah mov opBuffer,al StackPush , sub bp,bp Puts 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 , jmp @Begin @Case1: StackTop , 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 , mov opBuffer,'*' StackPush , GetChar mov bl,al jmp @Begin @Case1@Skip: call f call g cmp al,ah jb short @b ja short @a StackPop , cmp opBuffer,0ah jz short @End GetChar mov bl,al jmp @Begin @a: mov opBuffer,bl StackPush , GetChar mov bl,al sub bp,bp jmp @Begin @b: StackPop , StackLength cmp ax,0002h jnl short @Skip mov bl,opBuffer jmp short Error @Skip: StackPop , mov esi,opnBuffer StackPop , mov edi,opnBuffer call Operation mov opnBuffer,edi StackPush , jmp @Begin @End: StackLength cmp ax,0001h jnz short Error Puts StackPop , PutLong , ; @Return: ret main endp Error proc near Puts PutChar bx ClearStack ClearStack 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