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