简单的计算器模拟程序的设计和实现.docx
《简单的计算器模拟程序的设计和实现.docx》由会员分享,可在线阅读,更多相关《简单的计算器模拟程序的设计和实现.docx(26页珍藏版)》请在冰豆网上搜索。
简单的计算器模拟程序的设计和实现
简单的计算器模拟程序的设计和实现
1.问题描述
对任意给定的正确四则运算表达式,程序计算其结果值并输出。
程序无需查错功能,假定所输入的都是正确的四则运算表达式,并且表达式中运算分量均为无正负号整数,运算符为+、-、*、/,表达式以字符"="结束。
程序应有操作提示、输入和输出,界面追求友好,最好是菜单式的界面。
2.设计说明
2.1简要的分析
根据要求,要先输入包含有+,-,*,/的运算符的表达式,然后经过计算得到正确的答案。
从键盘中输入的是ASCII码,因此要将其转换为十进制的数据然后才能进行计算。
如果输入混合表达式,要将中缀式先变化成后缀式,然后再进行计算。
2.2概要分析
2.2.1定义的数据段
用于定义一些中间变量,并将显示在试验界面上,以及提示信息。
datasegment
stridb50dup(0)
expdb30dup(0)
trackdb30dup(0)
instrdb100dup(0)
msg0db'pleaseinputyourformular:
',0dh,0ah,'$'
msg1db0dh,0ah,'wronginput','$'
msg2db0dh,0ah,')and(doesnotmatch','$'
msg3db0dh,0ah,'divzeroerror','$'
msg4db0dh,0ah,'sorry,minusdataappears','$'
msg5db0dh,0ah,'anykeytocontinue,esctoexit','$'
dataends
2.2.2定义的堆栈段
声明用于将中缀表达式转换为后缀表达式,以及进行后缀表达式求值过程用到的堆栈段。
stacksegmentparastack
dw256dup(0)
stackends
2.2.3用到的子过程
2.2.3.1compare子过程
作用:
用于判断键盘输入的符号是否合法,若合法,则在屏幕上显示,否则报错。
2.2.3.2mult子过程
作用:
用于对输入的数字进行乘10累加操作,以便将连续输入的数字字符串转换为相对应的数值。
2.2.3.3trans子过程
作用:
将输入的中缀表达式转换为后缀表达式。
2.2.3.4value子过程
作用:
将后缀表达式结合堆栈结构进行表达式求值。
2.2.3.5divi子过程
作用:
通过除以10以及进一步处理将某数值转换为相应的ASCII字符串。
2.2.3.6print子过程
作用:
将表达式求值结果输出到屏幕上。
3.详细的算法描述
3.1.程序运行流程
3.2程序代码
STACKSEGMENTPARASTACK
DW256DUP(0)
STACKENDS
DATASEGMENT
STRIDB50DUP(0)
EXPDB30DUP(0)
TRACKDB30DUP(0)
INSTRDB100DUP(0)
MSG0DB'pleaseinputtheformular:
',0DH,0AH,'$'
MSG1DB0DH,0AH,'sorrry,wronginput','$'
MSG2DB0DH,0AH,')and(doesnotmatch','$'
MSG3DB0DH,0AH,'divbyzeroerror','$'
MSG4DB0DH,0AH,'sorry,minusdataappears','$'
MSG5DB0DH,0AH,'anykeytocontinue,esctoexit','$'
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,SS:
STACK,DS:
DATA
START:
MOVAX,STACK
MOVSS,AX
MOVAX,DATA
MOVDS,AX
MOVDX,OFFSETMSG0
MOVAH,9
INT21H
XORAX,AX
;READ
MOVBX,OFFSETINSTR
MOVDL,20H
JMPL2
COMPAREPROCNEAR
CMPAL,0DH
JZL2
MOVDL,AL
MOVAH,2
INT21H
RET
COMPAREENDP
L2:
MOVAH,8
INT21H
CALLCOMPARE
CMPAL,3DH;endwith'='
JZL2_OVER
MOVAH,39H
CMPAH,AL;delthewrongdata(>9)
JNBCONTI
MOVAH,2
MOVDL,8
INT21H
MOVDL,20H
INT21H
MOVDL,8
INT21H
JMPL2
CONTI:
CMPAL,28H;'('
JZL2_YES
CMPAL,29H
JZL2_YES;')'
CMPAL,2AH;'*'
JZL2_YES
CMPAL,2BH;'+'
JZL2_YES
CMPAL,2DH;'-'
JZL2_YES
CMPAL,2FH;'/'
JZL2_YES
;backfunction'<-'
CMPAL,08H
JNZNO_8
L2_NEXT:
PUSHDX
MOVDL,20H
MOVAH,2
INT21H
MOVDL,8
MOVAH,2
INT21H
CMPBX,OFFSETINSTR
JZL2
DECBX
MOVAL,0
MOV[BX],AL
POPDX
JMPL2
;
NO_8:
MOVAH,2FH
CMPAH,AL;delthewrongdata(<0)
JBL2_YES
MOVAH,2
MOVDL,8
INT21H
MOVDL,20H
INT21H
MOVDL,8
INT21H
JMPL2
L2_YES:
MOVDH,DL
MOVDL,AL
CMPDL,20H
JNZL2_NO20
CMPDH,20H
JZL2
L2_NO20:
MOV[BX],AL
INCBX
JMPL2
L2_OVER:
MOVAH,3DH
MOV[BX],AH
;checkinput
MOVSI,OFFSETINSTR
MOVAH,30H
MOVCH,0;record()
MOVCL,0
L3:
MOVAL,[SI]
INCSI
CMPAL,3DH
JZL3_OVER
CMPAL,2AH
JNBMAY_WRONG
CMPAL,29H
JZL3_29
INCCH
JMPL3_RIGHT
L3_29:
INCCL
JMPL3_RIGHT
MAY_WRONG:
CMPAL,30H
JNBL3_RIGHT
CMPAL,28H
JZL3_RIGHT
CMPAH,29H
JZL3_RIGHT
;cmpah,28h
;jzL3_right
CMPAH,30H
JNBL3_RIGHT
MOVDX,OFFSETMSG1
MOVAH,9
INT21H
JMPOVER3
L3_RIGHT:
MOVAH,AL
JMPL3
L3_OVER:
CMPCH,CL
JZINPUT_WRIGHT
MOVDX,OFFSETMSG2
MOVAH,9
INT21H
JMPOVER3
;
;chechover
INPUT_WRIGHT:
MOVBX,OFFSETSTRI
MOVSI,OFFSETINSTR
;read
READ:
;movah,1
;int21h
MOVAL,[SI];reservethedatabydecimal{test}
INCSI
MOVAH,28H;(
CMPAH,AL
JZIN_STRI
MOVAH,29H;)
CMPAH,AL
JZIN_STRI
MOVAH,2AH;*
CMPAH,AL
JZIN_STRI
MOVAH,2BH;+
CMPAH,AL
JZIN_STRI
MOVAH,2DH;-
CMPAH,AL
JZIN_STRI
MOVAH,2FH;/
CMPAH,AL
JZIN_STRI
MOVAH,2FH;deletethewronginput
CMPAH,AL
JNBREAD
MOVAH,3DH;=
CMPAH,AL
JZIN_STRI
MOVAH,39H;deletethewronginput
CMPAH,AL
JBREAD
CALLNEARPTRMULT
JMPREAD;theendofreserve
;
IN_STRI:
MOVAH,0
CMPAH,[BX]
JZNO_BX;incbx
INCBX
NO_BX:
MOV[BX],AL
MOVAH,3DH
CMPAH,AL
JNZNO_OVER
SUBAL,25;transplant'='to'$'
MOV[BX],AL
JMPOVER
NO_OVER:
JMPREAD
MULTPROCNEAR;multdata*10,addup
PUSHDX
PUSHCX
PUSHAX
MOVAH,0
CMP[BX],AH
JZNO_INC_BX
MOVAH,30H
CMP[BX],AH
JNBNO_INC_BX
INCBX
NO_INC_BX:
MOVDX,0
MOVCX,10
MOVAH,[BX]
CMPAH,30H
JBNO_SUB
SUBAH,30H
NO_SUB:
MOV[BX],AH
NEXT:
ADDDX,[BX]
LOOPNEXT
SUBAL,30H;trastodecimal
ADDDL,AL
MOV[BX],DL
MOVAH,[BX]
ADDAH,30H
MOV[BX],AH
POPAX
POPCX
POPDX
RET
MULTENDP
;
;endofread
OVER:
CALLNEARPTRTRANS;theoutletoftheprogram
OVER1:
CALLNEARPTRVALUE;jmpinsteadofretinproceduretrans
OVER2:
CALLNEARPTRPRINT
OVER3:
MOVAH,9
MOVDX,OFFSETMSG5
INT21H
MOVAH,8
INT21H
CMPAL,1BH
JZOVER4
MOVCX,210
MOVBX,OFFSETSTRI
MOVAL,0
OVER_LOOP:
MOV[BX],AL
INCBX
LOOPOVER_LOOP
MOVAH,2
MOVDL,0DH
INT21H
MOVDL,0AH
INT21H
JMPSTART
OVER4:
MOVAH,4CH
INT21H
;
;trans
TRANSPROCNEAR;
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHSI
PUSHDI
XORCX,CX
MOVBX,OFFSETSTRI
MOVSI,OFFSETEXP
MOVDI,OFFSETTRACK
TRANS_WHILE:
MOVAL,[BX]
INCBX
MOVAH,24H;'$'
CMPAH,AL
JZTRANS_OVER;endwith'='
MOVAH,2FH;judgeLdigital
CMPAH,AL
JNBNO_DIGITAL
MOV[SI],AL
INCSI
JMPTRANS_WHILE
NO_DIGITAL:
MOVAH,28H;judgeL'('
CMPAH,AL
JNZNO_9
MOV[DI],AL;pushal
INCDI
JMPTRANS_WHILE
NO_9:
MOVAH,29H;judgeL')'
CMPAH,AL
JNZNO_0
POP_WHILE:
DECDI
MOVAL,[DI];popal
MOVAH,28H
CMPAH,AL
JZOVER_POP_WHILE
MOV[SI],AL
INCSI
JMPPOP_WHILE
OVER_POP_WHILE:
;moval,dl
JMPTRANS_WHILE
NO_0:
MOVAH,2BH
CMPAH,AL
JZOR1_YES
MOVAH,2DH
CMPAH,AL;ifalis'+'or'-'
JNZNO_OR1
OR1_YES:
CMPDI,OFFSETTRACK;jmpifstackisblank
JZSTACK_BLANK
DECDI;popal
MOVCL,[DI]
MOVAH,28H
CMPAH,CL
JZOVER_OR1_YES
MOV[SI],CL
INCSI
JMPOR1_YES
OVER_OR1_YES:
MOV[DI],CL
INCDI
;reservethe')'
STACK_BLANK:
MOV[DI],AL;pushal
INCDI
JMPTRANS_WHILE
NO_OR1:
MOVAH,2AH
CMPAH,AL
JZOR2_YES
MOVAH,2FH
CMPAH,AL
JNZNO_OR2;ifalis'*'or'/'
OR2_YES:
DECDI;pushdl
MOVCL,[DI]
MOVAH,2AH
CMPAH,CL
JZOR2_YES_OR
MOVAH,2FH
CMPAH,CL
JNZOR2_OVER
OR2_YES_OR:
MOV[SI],CL
INCSI
JMPOR2_YES
OR2_OVER:
MOV[DI],CL
INCDI;pushal
MOV[DI],AL
INCDI
NO_OR2:
;moval,[bx]
;incbx
;
JMPTRANS_WHILE
TRANS_OVER:
CMPDI,OFFSETTRACK
JZPOP_OVER
DECDI
MOVAL,[DI]
MOV[SI],AL
INCSI
JMPTRANS_OVER
POP_OVER:
MOVAL,24H;endwith'='
MOV[SI],AL
POPDI
POPSI
POPDX
POPCX
POPBX
POPAX
JMPOVER1
TRANSENDP
;endoftrans
;startvalue
VALUEPROCNEAR;getthevalue
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHSI
MOVBX,OFFSETEXP
MOVSI,OFFSETTRACK
XORAX,AX
VALUE_WHILE:
MOVAL,[BX]
INCBX
MOVAH,24H
CMPAH,AL
JZVALUE_OVER
MOVAH,2FH;judgeLdigital
CMPAH,AL
JNBVALUE_NO_DIGITAL
SUBAL,30H
MOV[SI],AL
INCSI
JMPVALUE_WHILE
VALUE_NO_DIGITAL:
MOVAH,2BH;+
CMPAH,AL
JNZNO_ADD
DECSI
MOVDL,[SI]
DECSI
MOVDH,[SI]
ADDDH,DL
MOV[SI],DH
INCSI
JMPVALUE_WHILE
NO_ADD:
MOVAH,2DH;-
CMPAH,AL
JNZVALUE_NO_SUB
DECSI
MOVDL,[SI]
DECSI
MOVDH,[SI]
CMPDH,DL
JNBSUB_RIGHT
MOVDX,OFFSETMSG4
MOVAH,9
INT21H
JMPOVER3
SUB_RIGHT:
SUBDH,DL
MOV[SI],DH
INCSI
JMPVALUE_WHILE
VALUE_NO_SUB:
MOVAH,2AH;*
CMPAH,AL
JNZNO_MUL
DECSI
MOVDH,[SI]
DECSI
MOVAL,[SI]
MULDH
MOV[SI],AL
INCSI
JMPVALUE_WHILE
NO_MUL:
MOVAH,2FH;/
CMPAH,AL
JNZNO_DIV
DECSI
MOVDH,[SI]
DECSI
MOVAL,[SI]
XORAH,AH
CMPDH,0
JNZDIV_RIGHT
MOVDX,OFFSETMSG3
MOVAH,9
INT21H
JMPOVER3
DIV_RIGHT:
DIVDH
MOV[SI],AL
INCSI
NO_DIV:
JMPVALUE_WHILE
;
VALUE_OVER:
POPSI
POPDX
POPCX
POPBX
POPAX
RET
VALUEENDP
;endvalueprocedure
;
;startprint
PRINTPROCNEAR
PUSHAX
PUSHDX
;movdl,al
;movah,2
;int21h
;movdl,0dh
;movah,2
;int21h
;movdl,0ah
;movah,2
;int21h
MOVBX,OFFSETTRACK
CALLNEARPTRDIVI
DECAL
OK:
POPDX
POPAX
RET
PRINTENDP;endofprint
;
DIVIPROCNEAR;divdata/10funtion:
printthedata
PUSHBX
PUSHAX
PUSHDX
MOVAL,[BX]
XORAH,AH
XORCX,CX
NEXT1:
MOVBL,0AH
DIVBL
MOVDL,AH
ADDDL,30H
XORDH,DH
PUSHDX
INCCX
MOVDH,0H;judgeLtheend
CMPDH,AL
JNBDIVI_OVER1
XORAH,AH
JMPNEXT1
DIVI_OVER1:
POPDX
MOVAH,2
INT21H
LOOPDIVI_OVER1
MOVDL,20H
MOVAH,2
INT21H
POPDX
POPAX
POPBX
RET
DIVIENDP
;endofprint
CODEENDS
ENDSTART
4.测试结果
进行加法运算得到的结果为
进行结果为负数的减法运算
进行除数为0的除法运算
进行加减乘除混合运算
5.使用说明
当进入操作界面后,提示输入正确的表达式,以等号结束,然后程序给出正确结果。
输入的表达式只能含有加减乘除和数字括号,最后以等号结束。
程序计算的结果范围最大为65535,当输入结果超出范围,结果会溢出,给出错误答案。
6.总结
6.1设计过程中的体会
实验中为了模拟简单计算器,需要对输入的ASCII字符串进行处理,首先要将输入的表达式转换为相应的能被识别的正确的表达式,然后,对表达式进行有效处理,将中缀表达式转换为便于计算机计算的后缀表达式。
在进行计算的过程中,利用后缀表达式和堆栈结果是非常容易进行四则混合运算的。
但是,在设计的过程中,如何将中缀表达式转换为后缀表达式,是本实验的一个难点。
在试验的过程中,将中缀式转换成后缀式对我来说相当困难,因此在查阅大量资料和余同学讨论后,才完成相应目的。
因为本实验应用的是汇编语言进行设计,而汇编语言每次只能处理一个有效字符比如运算符,括号等和一个数值比如由ASCII码转换而来的相应的数值。
而且在中缀式向后缀式转换的过程中,也用到了堆栈结构。
6.2设计的优缺点
6.2.1优点
可以进行四则混合运算,并得到结果。
可以提示用户输入错误。
可以正确计算带括号的表达式。
6.2.2缺点
界面没有达到友好,人性化。
支持的数据处理较小。
7.设计体会
这次试验主要是模拟计算器的功能,在试验的过程中,我进一步熟悉了汇编语言的应用,了解到了汇编语言的使用格式和方法。
在程序的编写中,得到了很多同学的帮助,学会了将设计进行分层,简化了设计过程,降低了设计难度。
试验中使用到了算术运算指令,比较运算指令,循环运算指令,跳转指令,使我对这些指令的使用有了自己的体会和理解。
在程序的编写中,将中缀式变成后缀式,键盘输入的ASCII码和十进制数之间的转换,寻址方式与寄存器的结合都是重点内容,在编写的过程中得到了深刻理解。
通过这次实验,我明白了要学习的东西很多,并且要在实践中锻炼自己,提高自己的逻辑思考和编程设计能力。