微机设计报告(四则运算器)_第1页
微机设计报告(四则运算器)_第2页
微机设计报告(四则运算器)_第3页
微机设计报告(四则运算器)_第4页
微机设计报告(四则运算器)_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 学 院: 班 级: 姓 名: 学 号: 课程设计题目:四则运算计算器课程名称:汇编语言与微机原理评阅成绩:评阅意见:成绩评定教师签名:日期: 年 月 目 录概述1一、设计要求1二、设计思想1三、程序工作原理2四、程序流程图及说明3五、程序源代码7六、程序运行示例18七、设计过程中遇到的问题及解决方法18八、设计心得19九、参考文献19四则运算计算器概述此计算器,可以实现从键盘输入一个十进制的四则运算表达式,如:-3+4*(5-6)-8/2,编程计算表达式的值,输出十进制结果。表达式和结果可以是三位或四位十进制,也可以是带负数的十进制数,并且*/()位置任意摆放(只要符合数学上的运算逻辑)。一

2、、设计要求用汇编语言设计一个程序,用来实现计算器的四则运算功能。需要实现在屏幕要显示输入的表达式,以及运算结果。例如:-3+4*(5-6)-8/2计算表达式的结果,并将该表达式及结果显示出来; 设计要求如下:(1)由键盘作为输入部分。(2)能进行四则混合运算,并且能计算带括号和负数的数学表达式。(3)按 esc 键则退出计算器菜单界面并返回 dos 系统,否则继续输入表达式,求得对应的结果。二、设计思想根据题目的要求,可以把整个源程序大致划分六大步骤。(1) 首先键盘输入合法中缀算术表达式,并将其存储到s1中。(2) 然后调用子程序change将中缀式转化为后缀式。(3) 调用子程序calcu

3、late对后缀表达式进行有符号数的运算,并将最终结果存放在栈中。(4) pop ax,ax-storage,即用storage 存放最终运算结果。(5) 调用子程序output将运算结果输出。(6) 通过用键盘输入esc退出dos程序。三、程序工作原理步骤一的原理:此处用系统功能1号调用,每次从键盘输入一个字符,就将其存入到数组s1中,然后在判断此字符是否为回车,如果不是,则循环,继续输入字符,否则,程序往下执行。步骤二的原理:此处最核心的就是中缀表达式转化为后缀表达式的算法。具体思路为:用一个栈来存储与运算符号.先将字符压入栈中,并假设其优先级为0.然后遍历s1中的字符,遇到数字直接存入s2

4、中并且输完数字后向s2中输入一空格以备计算结果时用。遇到运算符则先判断其与栈顶运算符的优先级谁大。如果s1中运算符号优先级大,则此运算符号直接入栈;否则栈顶符号先出栈到s2,待栈顶符号优先级小于s1中符号时,s1中元素入栈。步骤三的原理:遍历s2中的字符,遇到空格,则将前面数字字符串转换成的数据压入栈中。遇到加号,从栈中弹出两个数据进行加法运算,并将运算结果压入栈中。遇到减号,从栈中弹出两个数据进行减法运算,并将运算结果压入栈中。遇到乘号,从栈中弹出两个数据进行乘法运算,并将运算结果压入栈中。遇到除号,从栈中弹出两个数据进行除法运算,并将运算结果压入栈中。整个字符串遍历完后,最终计算结果就保存

5、在栈中。步骤四的原理:将栈中保存的最后运算结果弹出,并保存到storage中。步骤五的原理:先判断运算结果是否为负数,如果是,将-存入数组n中,并对运算结果求补。然后判断数据所在范围,小于32767大于一万则将运算结果除以一万,并将商赋给数组n;然后将余数除以一千将商赋给数组n;再将余数除以一百并将商赋给数组n;再将余数除以十并将商赋给数组n;最终将余数赋给数组n。如果数据更小,也是如此实现,只是步骤更少些。步骤六的原理:通过ret output语句跳转到call output语句的下一条指令,执行next1模块(判断键盘输入是否为esc),若为esc的话跳转到exit模块从而退出程序。四、程

6、序流程图及说明程序总流程图:中缀表达式转化为后缀表达式的流程图: 其每次向s2中输入一个字符,di就会加1。当压入 (后,再压入0作为运算符优先级的判断;当压入+或-后,再压入01作为运算符优先级的判断;当压入*或/后,再压入02作为运算符优先级的判断。计算后缀表达式数值的流程图:输出运算结果程序的流程图:五、程序源代码data segments1 db 60 dup(?),$ ;存储输入的中缀表达式子s2 db 60 dup(?),$ ;存储后缀表达式子n db 10 dup(?),$ ;存储要输出的数字字符串storage dw ?,$ ;存储运算结果buf0 db 0dh,0ahdb*,

7、0dh,0ahdb* *,0dh,0ahdb* four arithmetic operation calculator *,0dh,0ahdb* this program is designed by *,0dh,0ahdb* wangyuli 200941843302 *,0dh,0ahdb* *,0dh,0ahdb*,0dh,0ah db please input +,-,*,/,() expression,0dh,0ah,$;buf1 db 0ah,0dh,*expression error!*$data endsstack segment stack db 40 dup(?)stac

8、k endscode segment assume cs:code,ds:data,ss:stackstart: mov ax,data mov ds,ax mov dx,offset buf0 ;输出字符串 mov ah,9 ;buf0,提示输入表达式 int 21h mov si,0 ;输入的第一个数为负数的处理方法 mov ah,1 int 21h cmp al,- jne ll ;如果al不等于-号则跳转到ll mov s1si,0 inc si ll: mov s1si,al ;将al的内容传送到偏移地址为si+s1(相对基址变址寻址)的储存单元 inc si lll: mov ah

9、,1 ;循环输入表达式 int 21h mov s1si,al inc si cmp al,0dh jne lll mov dl,0ah mov ah,2 int 21h call change ;调用中缀转后缀子程序 call calculate ;调用计算后缀表达式子程序exit: mov ah,4ch int 21h error:mov dx,offset buf1 ;输出字符串 mov ah,9 ;buf1,提示输入表达错误 int 21h jmp next1 next : pop ax ;从ax中弹出一个数据 cmp ax, ;比较这个数据是否为 je next1 ;是则跳转到nex

10、t1 mov storage,ax ;把ax赋给storage call output ;调用输出运算结果子程序next1: mov ah,7 ;从键盘输入一个字符不回显 int 21h cmp al,1bh ;判断这个字符是否为esc je exit change proc near ;中缀表达式转换为 mov ah,0 ;后缀表达式的子程序 mov dh,0 mov si,0 mov di,0 push di cha: mov al,s1si ;数组元素的个数读入al中 inc si cmp al,0dh je a cmp al,( je l1 ;al等于(跳转到l1 cmp al,+ j

11、e l2 cmp al,- je l3 cmp al,* je l4 cmp al,/ je l5 cmp al,) je b cmp al,0 jge c ;al大于或等于0转移到c jmp error ;跳转到error模块 l1: push ax ;对左括号的处理 mov ax,0 push ax cmp s1si,- jne cha mov s2di,0 inc di mov s2di, inc dil2: mov bp,sp ;对加法的处理 mov dl,bp cmp dl,01h jge l21 push ax mov dx,0101h push dx jmp chal21: po

12、p dx pop bx mov s2di,bl inc di jmp l2 e: je nextl3: mov bp,sp ;对减法的处理 mov dx,bp cmp dl,01h jge l31 push ax mov dx,0201h push dx jmp chal31: pop dx pop bx mov s2di,bl inc di ;di自加1 jmp l3b: je l6a:je l8l4: mov bp,sp ;对乘法的处理 mov dx,bp cmp dl,02h jge l41 push ax mov dx,0302h push dx jmp chal41: pop dx

13、pop bx mov s2di,bl inc di jmp l4c:jge l7 l5: mov bp,sp ;对除法的处理 mov dx,bp cmp dl,02h jge l51 push ax mov dx,0402h push dx jmp chal51: pop dx pop bx mov ds:s2di,bl inc di jmp l5d: je el6: mov bp,sp ;对右括号的处理 cmp byte ptr bp,0 jne l61 pop dx pop ax jmp chal61: pop dx pop bx mov s2di,bl inc di jmp l6 l7:

14、 cmp al,9 ;对数字的处理 jle l71l71: mov s2di,al inc di cmp byte ptr s1si,0 jge l72 mov al, mov s2di,al inc di jmp cha l72:cmp byte ptr s1si,9 jle l73 ;s1si小于等于9跳转到l73l73: mov al,si inc si jmp l71 l8: mov bp,sp cmp byte ptr bp,0 jg l81 pop ax jmp l9l81: pop dx pop bx mov s2di,bl inc di jmp l8 l9: mov s2di,

15、0dh retchange endpcalculate proc near ;计算后缀表达式子程序 mov si,0 mov di,0 mov ah,0 mov bx, push bxcal: mov al,s2di inc di cmp al,0dh je d cmp al, je cal cmp al,+ je f1 cmp al,- je f2 cmp al,* je f3 cmp al,/ je f4 cmp al,0 jge f5 jmp errorf5: cmp al,9 jle f51f51: mov dl,al and dl,0fh mov bl,10 mov al,0f52:

16、imul bl add al,dl cmp byte ptr s2di, jne f53 push ax jmp calf53:mov dl,s2di inc di and dl,0fh jmp f52 f4: pop dx ;除法运算 pop ax idiv dl and ax,000fh push ax jmp calf3: pop dx ;乘法运算 pop ax imul dl push ax jmp calf2: pop dx ;减法运算 pop ax sub ax,dx push ax jmp calf1: pop ax ;加法运算 pop dx add ax,dx push ax

17、jmp cal retcalculate endpoutput proc near ;输出运算结果子程序 mov si,0 mov ax,storage cmp ax,0 jge c1 neg ax ;取ax的补码 mov nsi,- ;将-存入数组n中 inc sic1: cmp ax,10000 ;大于等于一万则跳转到c11 jge c11 cmp ax,1000 ;大于等于1000则跳转到c12 jge c12 cmp ax,100 ;大于等于100则跳转到c2 jge c2 cmp ax,10 ;大于等于10则跳转到c3 jge c3 cmp ax,0 jge c4c11: mov d

18、x,0 mov bx,10000 idiv bx ;运算结果除以一万,并将商赋给数组n add al,30h mov ds:nsi,al inc si mov ax,dx jmp c1c12: mov dx,0 mov bx,1000 ;运算结果除以一千,并将商赋给数组n idiv bx add al,30h mov ds:nsi,al inc si mov ax,dx jmp c1c2: mov cl,100 ;运算结果除以一百,并将商赋给数组n idiv cl add al,30h mov ds:nsi,al inc si mov al,ah mov ah,0 jmp c1c3: mov

19、cl,10 ;运算结果除以一十,并将商赋给数组n idiv cl add al,30h mov ds:nsi,al inc si mov al,ah mov ah,0 jmp c1c4: add al,30h mov nsi,al inc si jmp c0c0:lea dx,n mov ah,9 int 21hret ;返回到call output后的下一条指令output endp code endsend start六、程序运行示例以下是输入一个带括号的四则混合运算表达式输出的结果:以下是输入一个带负数的四则混合运算表达式输出的结果:以下是输入高位十进制的四则混合运算表达式的输出结果:以

20、下是输入错误符号后报错,然后按esc退出的结果:七、设计过程中遇到的问题及解决方法(1)在这次设计过程中用到的工具是masm5,在这个编程环境下使用je,jmp,jge之类的语句不能跳转太长,很容易超出范围。所以只有在中途设置个跳转中转函数。例如设置中转函数为a,要跳到l8,先jmp 到a,然后a在jmp到l8。(2)在设计中缀表达式怎么转换成后缀表达式遇到了算术符号优先权的问题,后面通过一个栈来存放运算符,然后给每种运算符设定一个优先级别,例如,+、-为01,*、/为02。然后通过与s1中的字符串比较优先权,根据优先权的大小弹出响应的运算符参与数据运算。(3)考虑到计算器怎么才能实现带负数的运算,先判断运算结果是否为负数,如果是,将-存入数组n中,并对运算结果求补。(4)最后碰到了怎么实现通过按esc键退出程序,因为程序已经编译完成,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论