简单计算机程序设计Word文档下载推荐.docx
《简单计算机程序设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《简单计算机程序设计Word文档下载推荐.docx(23页珍藏版)》请在冰豆网上搜索。
(4)程序采用汇编语言在PC机上完成;
(5)写出系统需求分析、原理图和程序实现流程图;
(6)对结果进行分析;
(7)要求阅读相关参考文献不少于5篇;
(8)根据课程设计有关规范,按时、独立完成课程设计说明书。
时间安排:
(1)布置课程设计任务,查阅资料,确定方案四天;
(2)进行编程设计一周;
(3)完成课程设计报告书三天;
指导教师签名:
年月日
系主任(或责任教师)签名:
1.引言
1.1设计目的
本次课程设计的题目是用汇编语言实现一个简单的计算器,要求:
编写一个程序,每运行一次可执行程序,可以实现加减乘除四则运算。
计算器是最简单的计算工具,简单计算器具有加、减、乘、除四项运算功能。
通过使用汇编语言设计实现简单计算器,以此进一步了解和掌握对数据存储,寄存器的使用,加减乘除相关指令以及模块的调用等汇编语言知识的有效运用。
本次课程设计以实现一个基本功能完善,界面友好,操作简便易行的计算器为最终目的。
通过对具有加减乘除基本功能的计算器的设计实现,学会使用汇编语言实现输入输出模块的设计,模块合理调用的设计,加减乘除运算的判断以及退出程序的判断的设计。
通过对各种指令的合理使用,熟悉并加深对各种指令的用法。
学会使用汇编语言设计各个功能模块。
当实现各个程序模块后,学会通过程序的调用最终实现一个具有基本计算功能的简单计算器。
简单计算器项目设计,主要是对汇编语言运算的应用,要完成该项目必须对汇编的四则运算语法和逻辑有深入的了解。
除此之外,还必须对汇编各种指令、伪指令集和计算机系统有很好的了解。
1.2设计要求及需求分析
1.2.1设计要求
(3)回车后进行计算并以十进制显示结果
1.2.2需求分析
用8086汇编语言编写一个能实现四则混合运算计算器程序。
程序能实现键盘十进制运算表达式的输入和显示(例如输入:
“1+2*3-4”),按回车键后输出十进制表示的运算结果。
该计算器能够对输入的符号进行实时的读取和分析,它接收0-9,+、-,*,/,=符号,用来对操作数进行运算,如果输入的操作数大于9,还需要对数字进行数码转换;
如果识别用户输入ESC,那么计算器会提示退出消息,如果输入是L,它将会执行清屏操作。
程序将获取的有效运算符保存在内存中,当获取到回车键后,即刻进行运算操作,最终将运算结果显示在计算机屏幕上。
1.3软件运行环境
使用的设备及软件为8086兼容机及轻松汇编开发软件。
2.总体设计分析
2.1题目分析
根据题目要求,可以把程序的工作过程划分为运算表达式输入、计算式运算、结果输出三部分。
因此在编写程序时可以按此把程序大致划分为三个模块。
总体设计流程图如下图2.1所示
图2.1软件总体设计流程图
2.2设计概述
输入模块分为包含运算表达式合法性检查,只有输入+,-,*,/,=,0-9,ESC,L,才算合法,其中ESC是退出程序功能,L是清屏功能
表达式运算模块包含,数值正负性判断,ASCII码转换,数值计算模块。
输出模块分为两个部分,第一个部分是程序启动时的提示语句输出,第二部分是运算结果进行转换输出。
详细的流程和设计方案将在设计步骤中说明。
3.设计步骤
3.1运算表达式输入
用户通过键盘输入的运算表达式为一个ASCII码字符串,字符串的最后一个字符是“=”号。
对于这个运算表达式,“+、-、*、/、0~9、=,ESC,L”是合法的表达式内容,其他的字符则是无法进行运算的非法内容,因此需要首先进行表达式合法性检查。
另外,由于计算机能进行计算的是2进制的补码,因此还需要把以ASCII码表示的数值转换为补码的形式并加以保存。
当然,控制运算方式的符号也要进行保存。
因此,“运算表达式输入”这个模块可以细化为:
表达式合法性检查、数值的ASCII码到补码转换及保存、符号的保存三个小部分,如图3-1所示。
图3-1“运算表达式输入”的流程图
3.1.1运算表达式合法性的检查方法
观察“ASCII字符编码表”,可以发现“+、-、*、/”的ASCII码由2AH到2FH,而“0~9”的ASCII码则由30H到39H,因此只需对输入的字符一个一个地进行数值范围比较,看看是否处于28H~39H这个范围里面,即可区分输入的表达式是否合法,流程图如图5-2所示。
此流程图是采用循环输入字符的方法,每输入一个字符即进行判断。
图3-2运算表达式合法性检查
3.2数值的补码转换方法
要进行数值的ASCII码到补码的转换,首先就得判断输入的字符是数值还是符号。
根据上文所提,“+、-、*、/”的ASCII码由2AH到2FH,而“0~9”的ASCII码则由30H到39H,只需比较字符是否小于等于2FH(或小于30H)即可判断是否为符号,否则则是数值,如图3-2所示。
众所周知,要把一个ASCII码数值转换为二进制补码的形式,只需要对其减30H即可实现。
但如果输入的是多位数,例如123,那么计算机获得的是31H、32H、33H三个字节,即使分别对这三个字节进行减30H操作,也只是获得1、2、3三个数而已。
实际上可以利用加权的方法合并这几个数:
123=1×
100+2×
10+3×
1
但另一个问题是,由于输入是随机的,即输入的运算数有多少位是未知的,因此无法使用上面的方面静态确定每一位的权重。
这里介绍的方法是,每输入运算数的一位,则把前面的合并结果(称为原值)乘以10再与这一位相加,实现动态的加权合并。
例如:
令原值为0,输入1,结果为:
0×
10+1=1
输入2,结果为:
1×
10+2=12
输入3,结果为:
12×
10+3=123
即:
123=(((0×
10+1)×
10+2)×
10)+3。
数值的补码转换流程如图3-3所示,当然,在获得第一个数值输入前要先把原值设置为0。
图3-3数值的补码转换流程图
3.3表达式计算
由于运算表达式有多个数值和符号,而符号有不同的优先级别,因此上文提到的数值保存和符号保存应该分开两个地方进行保存,这样有利于表达式的计算算法设计。
下面把“+、-、*、/”称为运算符,+、-的运算优先级要低于*、/,在运算时要先处理优先级高的运算。
图3.4运算表达式的存储举例
观察图3.4的三条运算表达式,再联系四则混合运算的优先原则,可以归纳出几点:
数值的数量是运算符的数量加1(优先符不算),第1个运算符代表第1、2个数值的运算操作,第N个运算符代表第N、N+1个数值的运算操作……
每进行一次运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值,仍然满足(a)。
例如图3.4(a),当完成乘法运算后,数值存储区有408、56两个数,符号存储区有“+”一个运算符。
括号(优先符)的作用是把括号内的运算符的优先级别提高到比外部高。
因此,要实现运算表达式的运算,最重要的就是确定所有运算符的优先级别。
下面讨论运算符优先级别的编程设计方法。
3.3.1运算优先级别的静态确定法
此方法是完成了把整条运算表达式全部存入数值存储区和符号存储区后才开始对运算符优先级进行判断的方法:
设置“*、/”的优先级为2、“+、-”的优先级为1;
运用优先级别静态确定法处理图3.4的三条表达式的运算符,结果如图3.5所示。
其中图3.5的“12*34+56”,其数据与优先级如图3.5所示。
由于*的优先级高于+,那么计算时先计算12*34
图3.5运算符的静态优先级别
最后,由于四则混合运算遵循从左往右计算的原则,即相同优先级别的运算符靠左的优先。
因此,只需计算出符号存储区里面的所有运算符的优先级别,然后根据优先级的大小先后执行运算符对应的运算即可实现计算(当然每进行一次运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值)。
当数值存储区里面剩下一个数值时,运算结束,这个最后的数值就是运算的最终结果。
分析运算结果的特点:
运算结果为一个2进制补码,整数,如果数据长度为16位,则运算结果范围是:
-32768~32767。
运算结果的输出要解决的主要问题是:
正负数区分、补码到ASCII码转换并输出显示。
运算结果的输出流程如图3.6所示。
图3.6结果输出流程图
3.3.2正负数区分
运算结果有三种情况:
正整数、负整数、零。
运算结果以补码形式对这三种情况进行统一的存储,但显示输出时则有所不同。
负整数前面需要显示“-”号,因此需要对运算结果的符号进行判断。
另一方面,正整数和零的补码与原码相同,而负整数的补码则不一样。
把负整数进行取补码运算,把它转换为原码,可以实现运算结果统一的ASCII码转换输出方法,而不需要分别为正整数和零、负整数分别设计两个不同的ASCII码转换程序,如图3.7所示。
图3.7正负数区分流程图
3.3.3补码到ASCII码转换
计算结果在屏幕上的输出显示实际上是ASCII码的输出显示。
假设程序采用的数据长度为16位,则运算结果范围是:
-32768~32767,即屏幕最多得显示5位ASCII码。
由于上文已经把结果统一为原码,下面介绍如何把原码转换为ASCII码。
这个转换过程实际上跟上文的“数值的补码转换方法”是相反操作。
例如要把123在屏幕上输出显示,即要把123的百位、十位、个位分离,得到1、2、3,然后转换为31H、32H、33H三个ASCII码。
众所周知,把一位数转换为ASCII码只需加30H即可,下面介绍把一个多位数的各位分离的方法。
(a)除十法
分离方法是:
对一个多位数进行除10处理,得到的余数即为个位数,而商则是删除个位后的多位数。
对商反复进行除10处理,直到商为0为止,即可把各位数分离。
例如对123进行除十法处理:
123/10,商是12,余数是3
12/10,商是1,余数是2
1/10,商是0,余数是1
可见经过三次除十计算,得到的三个余数刚好就是对123的各位的分离结果。
接着只需分别对这些余数加30H即可转换为ASCII码,实现输出转换。
除十法的优点是不需要理会要输出的数值有多少位,不断除以10直到商为0即可;
缺点是得到的余数的顺序跟输出的方向相反,不方便输出。
例如上例得到的三个余数的顺序是3、2、1,加30H转换输出后屏幕显示为“321”,跟期望显示的顺序相反,要作进一步处理。
处理方法是把余数放进堆栈里面,然后再出栈显示。
由于堆栈是先进后出的,即可解决该输出的顺序问题。
图3.8除十法流程图
(b)除最高位法
分离方法是先除以10位数-1,得到的商即为最高位,余数为删除最高位后的多位数。
接着令余数除以10位数-2,得到的商为次高位,……。
例如123,其位数是3(个位、十位、百位),则计算过程为:
123/103-1,商是1,余数是23
23/103-2,商是2,余数是3
3/103-3,商是3,余数是0
可见经过三次计算,得到的三个商刚好是对123的各位的分离结果,而且顺序跟输出方向相同。
可以直接加30H转换输出,屏幕显示为“123”。
该方法的缺点是:
必须首先确定要输出的数值有多少位,编程者必须十分清楚需要输出的数值的数值范围。
本次软件设计过程中用的是(a)除十法
图3.9除最高位法流程图