1、微机应用系统设计与综合实验设计报告 第一章 实验课题与要求1.1课程在教学计划中的地位和作用微机应用系统设计与综合实验课程是测控技术专业本科生必修的一门技术基础课程。通过该课程的学习使学生对微机系统有一个全面的了解、掌握常规芯片的使用方法、掌握简单微型计算机应用系统软硬的设计方法。通过课程设计进一步锻炼我们在微型计算机应用方面的实际工作能力。计算机科学在应用上得到飞速发展,因此,学习这方面的知识必须紧密联系实际:掌握这方面的知识更要强调解决实际问题的能力。我们要着重学会面对一个实际问题,如何去自己收集资料,如何自己去学习新的知识,如何自己去制定解决问题的方案并通过实践不断地去分析和解决前进道路
2、上的一切问题,最终到达胜利的彼岸。1.2实验课题与要求1.2.1实验课题课题:四则混合运算器程序设计设计内容:按照屏幕提示输入算术表达式,例如:3+2,9*5,10-5,45/2等,然后计算相应的表达式的结果并按十进制形式输出显示。按ESC键则退出计算器菜单界面并返回dos系统,否则继续输入表达式,求得对应的结果。1.2.2实验要求实验设计要求:1.遵循模块化、结构化的程序设计方法。2.要求程序必须正确。3.程序简明易懂,多运用输入输出提示,出错信息及必要的注释。4.要求程序结构合理,语句使用得当。5.适当追求编程技巧和程序运行效率。 1.2.3工作条件使用的设备及软件为8086兼容机及MAS
3、M汇编开发软件。1.2.4运算器功能简介本计算器具体来说有以下功能和特点:(1)输入一个正数后按回车可以直接输出该正数;(2)输入一个负数后按回车可以直接输出该负数;(3)可以进行有符号数的加运算;(4)可以进行有符号数的减运算;(5)可以进行有符号数的加、减运算;(6)可以进行有符号数的乘运算; (7)可以进行有符号数的除运算;(8)可以进行有符号数的乘、除运算;(9)可以进行有符号数的加、减、乘、除四则运算;(10)支持使用括号改变运算顺序;(11)输入一个数值不是很大的合法的算术表达式并按回车,可以得到正确的结果;(12)程序采用的数据长度为16位,运算结果范围是:-3276832767
4、.第二章 程序设计方案2.1程序需求分析该程序设计的关键是要根据四则运算中( )、*、/、+、-、= 的优先级设置符号的权值,其中(、*、/、+、-、)、= 的权值分别设置为5、4、4、3、3、1、0 ,然后根据权值的大小进行运算。程序使用数字标志SIGN1、括号标志SIGN2分别来判断数字是否输入完毕和括号是否配对,另外程序定义两个数据存储区域 NUMB和MARK,其中NUMB用来保存输入的或运算的数值,MARK用来保存输入的符号及其对应的权值。程序不断判断输入的符号是否是左括号( ,当遇到左括号是在存储区MARK保存其符号,紧跟着将( 的权值改为2并保存之,这是为了使程序运算括号内的表达式
5、,当遇到右括号)时括号内运算将结束。需要注意的是程序执行完括号内表达式的运算及乘除运算后将在存储区MARK中覆盖符号(、)、*、/ 及紧跟着的权值,使得程序在运算整个四则运算表达式时当括号内表达式的运算及乘除运算结束后存储区MARK中只有 +、- 运算符及紧跟着的权值,然后按照+、- 运算符的左右顺序从左到右进行 +、- 运算,当最后遇到等号 = 时输出表达式的数值,然后再根据提示判断是否继续执行下一个四则运算表达式2.2主程序流程图开始清屏初始化首地址输出欢迎界面输入字符ERROR是数字、符号还是= =(SIGN2)=0 N 是符号 是数字 Y 保存数值(SIGN1)=0 Y NDI+2 (
6、SIGN1)=0设置符号权值是否是( N是否是) Y(SIGN2)+1 N Y (SIGN2)-1(SI)=M Y N(CH)(SI) Y N(SI) =(是否是等号 Y N N YSI-1SI-1是否是) YCL= (SI) N是何种运算SI+1(SI)=AL进行相应的运算SI+1是否是( Y (CH)=2 N( SI) =(CH)初始化首地址输出表达式的值DI+2输入字符是否为ESC N Y结束 图2.1 总流程图第三章 程序各模块的设计3.1题目分析根据题目要求,可以把程序的工作过程划分为运算表达式输入、计算、结果输出三部分。因此在编写程序时可以按此把程序大致划分为三个模块。3.2 运算
7、表达式输入用户通过键盘输入的运算表达式为一个ASCII码字符串,字符串的最后一个字符是“=”号。对于这个运算表达式,“+、-、*、/、(、)、09、=”是合法的表达式内容,其他的字符则是无法进行运算的非法内容,因此需要首先进行表达式合法性检查。另外,由于计算机能进行计算的是2进制的补码,因此还需要把以ASCII码表示的数值转换为补码的形式并加以保存。当然,控制运算方式的符号也要进行保存。因此,“运算表达式输入”这个模块可以细化为:表达式合法性检查、数值的ASCII码到补码转换及保存、符号的保存三个小部分,如图3.1所示。图3.1 “运算表达式输入”的流程图3.2.1 运算表达式合法性的检查方法
8、 观察“ASCII字符编码表”,可以发现“+、-、*、/、(、)”的ASCII码由28H到2FH,而“09”的ASCII码则由30H到39H,因此只需对输入的字符一个一个地进行数值范围比较,看看是否处于28H39H这个范围里面,即可区分输入的表达式是否合法,流程图如图3.2所示。此流程图是采用循环输入字符的方法,每输入一个字符即进行判断。读者也可以采用输入字符串的方法,把整个运算表达式接收完毕后再进行判断。图3.2 运算表达式合法性检查流程图一 另一方面,对于含有括号的运算表达式,当左括号的数量与右括号数量不相等时,表达式也是非法的。因此,可以设置一个起始值为0的变量(下面称其为配对标志),当
9、输入“(”时此变量加一,当输入“)”时减一,则当表达式输入结束时,只需判定此配对标志是否为0,即可判定左右括号数量是否相等。图3.3 运算表达式合法性检查流程图二3.2.2 数值的补码转换方法要进行数值的ASCII码到补码的转换,首先就得判断输入的字符是数值还是符号。根据上文所提,“+、-、*、/、(、)”的ASCII码由28H到2FH,而“09”的ASCII码则由30H到39H,只需比较字符是否小于等于2FH(或小于30H)即可判断是否为符号,否则则是数值,如图2所示。众所周知,要把一个ASCII码数值转换为二进制补码的形式,只需要对其减30H即可实现。但如果输入的是多位数,例如123,那么
10、计算机获得的是31H、32H、33H三个字节,即使分别对这三个字节进行减30H操作,也只是获得1、2、3三个数而已。实际上可以利用加权的方法合并这几个数:123110021031但另一个问题是,由于输入是随机的,即输入的运算数有多少位是未知的,因此无法使用上面的方面静态确定每一位的权重。这里介绍的方法是,每输入运算数的一位,则把前面的合并结果(称为原值)乘以10再与这一位相加,实现动态的加权合并。例如:令原值为0,输入1,结果为:01011输入2,结果为:110212输入3,结果为:12103123即:123(0101)102)10)3。数值的补码转换流程如图4所示,当然,在获得第一个数值输入
11、前要先把原值设置为0。图3.4 数值的补码转换流程图由于符号全部是一个字节,无需进行任何转换即可保存,处理简单,这里不作探讨。3.3 计算 由于运算表达式有多个数值和符号,而符号有不同的优先级别,因此上文提到的数值保存和符号保存应该分开两个地方进行保存,这样有利于表达式的计算算法设计。下面把“+、-、*、/”称为运算符,把“(、)”称为优先符。图3.5 运算表达式的存储举例观察图5的三条运算表达式,再联系四则混合运算的优先原则,可以归纳出几点:(1)数值的数量是运算符的数量加1(优先符不算),第1个运算符代表第1、2个数值的运算操作,第N个运算符代表第N、N+1个数值的运算操作(2)每进行一次
12、运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值,仍然满足(a)。例如图3.5(a),当完成乘法运算后,数值存储区有408、56两个数,符号存储区有“+”一个运算符。(3)括号(优先符)的作用是把括号内的运算符的优先级别提高到比外部高。因此,要实现运算表达式的运算,最重要的就是确定所有运算符的优先级别。下面讨论运算符优先级别的编程设计方法。3.3.1 运算优先级别的静态确定法此方法是完成了把整条运算表达式全部存入数值存储区和符号存储区后才开始对运算符优先级进行判断的方法:(1)设置“*、/”的优先级为2、“+、-”的优先级为1;(2)括号内部的所有运算符的优先级全部加2。运用优先
13、级别静态确定法处理图3.5的三条表达式的运算符,结果如图3.6所示。其中图3.6(c)的“34+56-8”由于被括号括起两次,因此其两个运算符“+、-”的优先级别均加了两次2。图3.6 运算符的静态优先级别 最后,由于四则混合运算遵循从左往右计算的原则,即相同优先级别的运算符靠左的优先。因此,只需计算出符号存储区里面的所有运算符的优先级别,然后根据优先级的大小先后执行运算符对应的运算即可实现计算(当然每进行一次运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值)。当数值存储区里面剩下一个数值时,运算结束,这个最后的数值就是运算的最终结果。 请同学们自行设计此算法的流程图。3.3.2
14、 运算优先级别的动态确定法运算优先级别静态确定法具有容易理解、实现简单的优点,而其缺点是:如果运算表达式太长、太多数值和符号时,则会占用较多的存储空间,而且计算优先级的工作量也会增多。动态确定法是在运算表达式未结束输入即开始计算的一种方法。由于在表达式输入阶段已开始计算,因此计算结果的速度比静态确定法快。观察图3.5(a),当用户输入“+”时,已经可以开始计算“12*34”;观察图3.5(b),当用户输入“-”时,已经可以开始计算“34+56”;观察图3.5(c),当用户输入第一个“-”时,已经可以开始计算“12*21”。也就是说,当用户输入的运算符的优先级不大于前一个运算符时,即可开始前一个
15、运算符的计算。问题是,对于有括号的运算表达式,在用户没有完成运算表达式的全部输入前,很难提前确定括号内部运算符的优先级。为了解决这个问题,动态确定法把优先符(括号)也赋予了优先级:(1)“(”,优先级为5;(2)“*、/”,优先级为4;(3)“+、-”,优先级为3;(4)“)”,优先级为1。计算图3.5三条运算表达式的所有符号的优先级别,结果如图3.7所示。图3.7运算符的动态优先级别设计计算的条件:(1) 只有优先级为3、4的符号(即+、-、*、/)可以进行计算;(2) 如果某符号的优先级大于等于下一个的优先级时,对此符号进行相应运算(当然每进行一次运算,相应的运算符即被消除,而参与运算的两
16、个数值合并为一个数值);(3) 如果左右括号相邻,且左括号在右括号左边时(即在符号存储区里面出现“()”的情况,或者在优先级队列里出现“51”的情况),把这对括号消除掉。最后,当数值存储区里面剩下一个数值(或者符号存储区里面没有符号)时,运算结束,这个最后的数值就是运算的最终结果。请同学们自行设计此算法的流程图。3.4 结果输出当数值存储区里面剩下一个数值(或者符号存储区里面没有符号)时,运算结束,需要把运算结果输出显示。分析运算结果的特点:运算结果为一个2进制补码,整数,如果数据长度为16位,则运算结果范围是:-3276832767。运算结果的输出要解决的主要问题是:正负数区分、补码到ASC
17、II码转换并输出显示。运算结果的输出流程如图3.8所示。图3.8 结果输出流程图3.4.1 正负数区分运算结果有三种情况:正整数、负整数、零。运算结果以补码形式对这三种情况进行统一的存储,但显示输出时则有所不同。负整数前面需要显示“-”号,因此需要对运算结果的符号进行判断。另一方面,正整数和零的补码与原码相同,而负整数的补码则不一样。把负整数进行取补码运算,把它转换为原码,可以实现运算结果统一的ASCII码转换输出方法,而不需要分别为正整数和零、负整数分别设计两个不同的ASCII码转换程序,如图3.9所示。图3.9 正负数区分流程图3.4.2 补码到ASCII码转换计算结果在屏幕上的输出显示实
18、际上是ASCII码的输出显示。假设程序采用的数据长度为16位,则运算结果范围是:-3276832767,即屏幕最多得显示5位ASCII码。由于上文已经把结果统一为原码,下面介绍如何把原码转换为ASCII码。这个转换过程实际上跟上文的“数值的补码转换方法”是相反操作。例如要把123在屏幕上输出显示,即要把123的百位、十位、个位分离,得到1、2、3,然后转换为31H、32H、33H三个ASCII码。众所周知,把一位数转换为ASCII码只需加30H即可,下面介绍把一个多位数的各位分离的方法。(1)除十法分离方法是:对一个多位数进行除10处理,得到的余数即为个位数,而商则是删除个位后的多位数。对商反
19、复进行除10处理,直到商为0为止,即可把各位数分离。例如对123进行除十法处理:123/10,商是12,余数是312/10,商是1,余数是21/10,商是0,余数是1可见经过三次除十计算,得到的三个余数刚好就是对123的各位的分离结果。接着只需分别对这些余数加30H即可转换为ASCII码,实现输出转换。除十法的优点是不需要理会要输出的数值有多少位,不断除以10直到商为0即可;缺点是得到的余数的顺序跟输出的方向相反,不方便输出。例如上例得到的三个余数的顺序是3、2、1,加30H转换输出后屏幕显示为“321”,跟期望显示的顺序相反,要作进一步处理。处理方法是把余数放进堆栈里面,然后再出栈显示。由于
20、堆栈是先进后出的,即可解决该输出的顺序问题。图3.10 除十法流程图(2)除最高位法分离方法是先除以10位数-1,得到的商即为最高位,余数为删除最高位后的多位数。接着令余数除以10位数-2,得到的商为次高位,。例如123,其位数是3(个位、十位、百位),则计算过程为:123/103-1,商是1,余数是2323/103-2,商是2,余数是33/103-3,商是3,余数是0可见经过三次计算,得到的三个商刚好是对123的各位的分离结果,而且顺序跟输出方向相同。可以直接加30H转换输出,屏幕显示为“123”。该方法的缺点是:必须首先确定要输出的数值有多少位,编程者必须十分清楚需要输出的数值的数值范围。
21、图3.11 除最高位法流程图第四章 课程设计中遇到的问题及解决方法。第五章程序清单和程序注释,相关流程图。;-;-数据定义-DSEG SEGMENTSTR1 DB 0AH,0DH, *$STR2 DB 0AH,0DH, * *$STR3 DB 0AH,0DH, * welcome you ! *$STR4 DB 0AH,0DH, * *$STR5 DB 0AH,0DH, * this is programme of sizeyunshuan *$STR6 DB 0AH,0DH, * rang(-32768 to 32767) *$STR7 DB 0AH,0DH, * press q to ex
22、it ! *$STR8 DB 0AH,0DH, * copyright by linjieling *$STR9 DB 0AH,0DH, * please input the formula: *$STR10 DB 0AH,0DH, *$SIGN1 DW 0 ;判断数字是否输入完毕SIGN2 DW 0 ;判断括号是否配对NUMB DW 20H DUP(0) ;保存输入的数值MARK DB A ;保存输入的运算符 DB 10H DUP(0) ;ERROR DB YOUR INPUT ARE WRONG$ DSEG ENDS;-宏定义-DISP MACRO M ;字符串输出 LEA DX,M ;将
23、M的偏移地址传送给DX寄存器 MOV AH,9 ;其中09H是字符串输出 INT 21H ;通过给AH寄存器赋值,再调用INT 21H指令,根据AH寄存器中的值执行相应的操作 ENDMCHOICE MACRO ASC1,HAO1,HH ;宏定义,给运算符赋权值 CMP AL,ASC1 ;比较键盘输入的运算符(运算符的ASC码存放在AL寄存器)与ASC1 JNE OTHER&HAO1 ;若不等,则往下执行OTHER1,如此类推 MOV CH,HH ;将运算符的权值(即优先级高低值)传送到CH寄存器 JMP OTHER7 ;执行后,返回 ENDM;-CSEG SEGMENT ;ASSUME CS:
24、CSEG,DS:DSEGSTART: CALL CLEARMOV AX,DSEG ;MOV DS,AX ;LEA DI,NUMB ;将NUMB的偏移地址传送到DI,NUMB存储单元中存放输入的数值LEA SI,MARK ;将MARK的偏移地址传送到SI,MARK存储单元中存放输入的运算符 DISP STR1;显示字符串 DISP STR2 DISP STR3 DISP STR4 DISP STR5 DISP STR6 DISP STR7 DISP STR8 DISP STR9 DISP STR10 MOV AX,0;数据寄存器清零 MOV DX,0 MOV BX,0 MOV CX,0 STA1
25、 : CALL CR ;回车换行;-初始化-INPUT: MOV AH,1 ;其中1H是键盘输入并回显,AL中有输入字符INT 21H ;通过给AH寄存器赋值,再调用INT 21H指令,根据AH寄存器中的值执行相应的操作;-输入字符- CMP AL,q JE J_SHU;-若输入q,则返回dos状态-CMP AL,= ;JE PD ;判断配对标志位;-是等号,进一步判断输入括号是否配对-CMP AL,28H ;JB BC ;JB为小于就跳转CMP AL,39H ;JA BC ;JA为大于就跳转;-输入字符的ASC码小于28H或大于39H,则继续输入-CMP AL,2FH ;判断是数字还是符号J
26、BE JUD ;是符号转入响应操作;-INC WORD PTR SIGN1 ;将数字标志位加1SUB AL,30H ;将ASC码转16进制MOV AH,0 ;XCHG AX,DI ;互换两个操作数的存放位置,实现字交换MOV BX,10 ;MUL BX ;无符号数乘法指令XCHG AX,DI ;ADD DI,AX ; JMP INPUT ;-输入为数值时的操作-PD: CMP WORD PTR SIGN2,0 ;判断配对标志位JE JUD ;跳到判断数值是否输入完毕 JMP BC ;不配对则显示ERROR;-JUD: CMP WORD PTR SIGN1,0 ;判断数值是否输入完毕JE FUH
27、1 ;跳到判断优先级ADD DI,2 ;DI向下移一个字MOV WORD PTR SIGN1,0;数值标志位清零;-FUH1: CALL ADVANCE ;判定优先级CMP CH,5 ;判断输入的运算符中是否有左括号JNE PY ;不是,则判断输入的运算符中是否有右括号;-INC WORD PTR SIGN2 ;是左括号,括号标志位加1;-PY: CMP CH,1 ;判断输入的是否是右括号JNE AGAIN ;跳到判断运算存储区是否为空DEC WORD PTR SIGN2 ;是右括号,括号标志位减1;-AGAIN: CMP BYTE PTRSI,A;判断运算符存储区是否为空JE SAVE ;判
28、断输入是否为=CMP CH,SI ;JA SAVE ;计算高优先级的 SI指向运算符,每个运算符都有相应的权值CMP BYTE PTRSI,(JNE YIDO;寻找左括号DEC SI;是左括号,还是向上移,判断左括号前边是否还有运算符JMP INPUT;- YIDO: DEC SI ;SI向上移MOV CL,SI ;将运算符传送给CLCALL MATCH ;判断是什么运算符并进行相应的计算JMP AGAIN ;判断运算符存储区是否为空;-SAVE: CMP CH,0 ;JE OVER ;=时,则输出结果CMP CH,1 ;JE INPUT ;“)”不保存,输入下一个数INC SI ;MOV S
29、I,AL ;INC SI ;CMP CH,5 ;JNE GO_ON ;MOV CH,2 ;改变(的权值GO_ON: MOV SI,CH ;JMP INPUT ;-BC: LEA DX,ERROR ;将ERROR的偏移地址给DXMOV AH,9 ;INT 21H ;CALL CRJMP J_SHU1 ;-四则运算子程序-MATCH PROC ;子程序,进行相应的运算PUSH AX ;XOR AX,AX;异或XOR BX,BX;-乘法运算-CMP CL,2AH ;乘法运算JNE NEXT1SUB DI,2XCHG BX,DISUB DI,2XCHG AX,DIIMUL BXMOV DI,AXADD
30、 DI,2JMP FINISH;-;-除法运算-NEXT1: CMP CL,2FH ;除法运算JNE NEXT2SUB DI,2XCHG BX,DISUB DI,2 XCHG AX,DICWDIDIV BXMOV DI,AXADD DI,2JMP FINISH;-;-加法运算-NEXT2: CMP CL,2BH ;加法运算JNE NEXT3SUB DI,2XCHG BX,DISUB DI,2ADD DI,BXADD DI,2JMP FINISH;-;-减法运算-NEXT3: CMP CL,2DH ;减法运算JNE FINISHSUB DI,2XCHG BX,DISUB DI,2SUB DI,B
31、X ADD DI,2FINISH: POP AX RETMATCH ENDP;-;-定义优先级-ADVANCE PROCCHOICE 28H,1,5 ;( 28H为 ( 的ASCII码OTHER1: CHOICE 29H,2,1 ;)OTHER2: CHOICE 2AH,3,4 ;*OTHER3: CHOICE 2FH,4,4 ;/OTHER4: CHOICE 2BH,5,3 ;+OTHER5: CHOICE 2DH,6,3 ;-OTHER6: CHOICE 3DH,7,0 ;=OTHER7: RETADVANCE ENDP;-;-*清屏*-Clear PROC NEAR PUSH AX PU
32、SH BX PUSH CX PUSH DX MOV AH,06H MOV AL,00H MOV CH,0 MOV CL,0 MOV BH,0FH MOV DH,18H MOV DL,4FH INT 10H MOV BH,0 MOV DX,0 MOV AH,02H INT 10H POP DX POP CX POP BX POP AX RETClear ENDP;-;-*回车换行*-CR PROC PUSH AX PUSH DX MOV AH,2 MOV DL,13;回车 INT 21H MOV AH,2 MOV DL,10;换行 INT 21H POP DX POP AX RETCR ENDP;-OVER: SUB DI,2CMP WORD PTRDI,0JGE W1NEG WORD PTRDIMOV DL,-MOV AH,2INT 21H;-W1: MOV BX,10000MOV CX,5MOV SI,0;-W2: MOV AX,DIMOV DX,0DIV BXMOV DI,DXCMP AL,0JNE W3CMP SI,0JNE W3CMP CX,1JE W3JMP W4;-W3: MOV D