汇编计算器互联网

上传人:仙*** 文档编号:37724040 上传时间:2021-11-04 格式:DOC 页数:14 大小:790KB
返回 下载 相关 举报
汇编计算器互联网_第1页
第1页 / 共14页
汇编计算器互联网_第2页
第2页 / 共14页
汇编计算器互联网_第3页
第3页 / 共14页
点击查看更多>>
资源描述
1 项目特点及目的 本课程设计是一次程序设计方法及技能的基本训练,通过实际程序的开发及调试,巩固课堂上学到的关于程序设计的基本知识和基本方法,进一步熟悉汇编语言的结构特点和使用,达到能独立阅读、设计编写和调试具有一定规模的汇编程序的水平。2 题目简介 用8086汇编语言编写一个能实现四则混合运算、带括号功能的整数计算器程序。程序能实现键盘十进制运算表达式的输入和显示(例如输入:“1+2*(3-4)”),按“=”后输出十进制表示的运算结果。3 程序设计要求u 遵循模块化、结构化的编程思路u 程序必须正确运行u 程序简明易懂,多标明注释,具有良好的程序书写风格u 适当优化程序,提高程序的运行效率4 工作条件使用的设备及软件为8086兼容机及MASM汇编开发软件。5 题目分析根据题目要求,可以把程序的工作过程划分为运算表达式输入、计算、结果输出三部分。因此在编写程序时可以按此把程序大致划分为三个模块。5.1 运算表达式输入用户通过键盘输入的运算表达式为一个ASCII码字符串,字符串的最后一个字符是“=”号。对于这个运算表达式,“+、-、*、/、(、)、09、=”是合法的表达式内容,其他的字符则是无法进行运算的非法内容,因此需要首先进行表达式合法性检查。另外,由于计算机能进行计算的是2进制的补码,因此还需要把以ASCII码表示的数值转换为补码的形式并加以保存。当然,控制运算方式的符号也要进行保存。因此,“运算表达式输入”这个模块可以细化为:表达式合法性检查、数值的ASCII码到补码转换及保存、符号的保存三个小部分,如图1所示。图1 “运算表达式输入”的流程图5.1.1 运算表达式合法性的检查方法 观察“ASCII字符编码表”,可以发现“+、-、*、/、(、)”的ASCII码由28H到2FH,而“09”的ASCII码则由30H到39H,因此只需对输入的字符一个一个地进行数值范围比较,看看是否处于28H39H这个范围里面,即可区分输入的表达式是否合法,流程图如图2所示。此流程图是采用循环输入字符的方法,每输入一个字符即进行判断。读者也可以采用输入字符串的方法,把整个运算表达式接收完毕后再进行判断。图2 运算表达式合法性检查流程图一 另一方面,对于含有括号的运算表达式,当左括号的数量与右括号数量不相等时,表达式也是非法的。因此,可以设置一个起始值为0的变量(下面称其为配对标志),当输入“(”时此变量加一,当输入“)”时减一,则当表达式输入结束时,只需判定此配对标志是否为0,即可判定左右括号数量是否相等。图3运算表达式合法性检查流程图二5.1.2 数值的补码转换方法要进行数值的ASCII码到补码的转换,首先就得判断输入的字符是数值还是符号。根据上文所提,“+、-、*、/、(、)”的ASCII码由28H到2FH,而“09”的ASCII码则由30H到39H,只需比较字符是否小于等于2FH(或小于30H)即可判断是否为符号,否则则是数值,如图2所示。众所周知,要把一个ASCII码数值转换为二进制补码的形式,只需要对其减30H即可实现。但如果输入的是多位数,例如123,那么计算机获得的是31H、32H、33H三个字节,即使分别对这三个字节进行减30H操作,也只是获得1、2、3三个数而已。实际上可以利用加权的方法合并这几个数:123110021031但另一个问题是,由于输入是随机的,即输入的运算数有多少位是未知的,因此无法使用上面的方面静态确定每一位的权重。这里介绍的方法是,每输入运算数的一位,则把前面的合并结果(称为原值)乘以10再与这一位相加,实现动态的加权合并。例如:令原值为0,输入1,结果为:01011输入2,结果为:110212输入3,结果为:12103123即:123(0101)102)10)3。数值的补码转换流程如图4所示,当然,在获得第一个数值输入前要先把原值设置为0。图4 数值的补码转换流程图由于符号全部是一个字节,无需进行任何转换即可保存,处理简单,这里不作探讨。5.2 计算 由于运算表达式有多个数值和符号,而符号有不同的优先级别,因此上文提到的数值保存和符号保存应该分开两个地方进行保存,这样有利于表达式的计算算法设计。下面把“+、-、*、/”称为运算符,把“(、)”称为优先符。图5 运算表达式的存储举例观察图5的三条运算表达式,再联系四则混合运算的优先原则,可以归纳出几点:(a) 数值的数量是运算符的数量加1(优先符不算),第1个运算符代表第1、2个数值的运算操作,第N个运算符代表第N、N+1个数值的运算操作(b) 每进行一次运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值,仍然满足(a)。例如图5(a),当完成乘法运算后,数值存储区有408、56两个数,符号存储区有“+”一个运算符。(c) 括号(优先符)的作用是把括号内的运算符的优先级别提高到比外部高。因此,要实现运算表达式的运算,最重要的就是确定所有运算符的优先级别。下面讨论运算符优先级别的编程设计方法。5.2.1 运算优先级别的静态确定法此方法是完成了把整条运算表达式全部存入数值存储区和符号存储区后才开始对运算符优先级进行判断的方法:n 设置“*、/”的优先级为2、“+、-”的优先级为1;n 括号内部的所有运算符的优先级全部加2。运用优先级别静态确定法处理图5的三条表达式的运算符,结果如图6所示。其中图6(c)的“34+56-8”由于被括号括起两次,因此其两个运算符“+、-”的优先级别均加了两次2。图6 运算符的静态优先级别 最后,由于四则混合运算遵循从左往右计算的原则,即相同优先级别的运算符靠左的优先。因此,只需计算出符号存储区里面的所有运算符的优先级别,然后根据优先级的大小先后执行运算符对应的运算即可实现计算(当然每进行一次运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值)。当数值存储区里面剩下一个数值时,运算结束,这个最后的数值就是运算的最终结果。 请同学们自行设计此算法的流程图。5.2.2 运算优先级别的动态确定法运算优先级别静态确定法具有容易理解、实现简单的优点,而其缺点是:如果运算表达式太长、太多数值和符号时,则会占用较多的存储空间,而且计算优先级的工作量也会增多。动态确定法是在运算表达式未结束输入即开始计算的一种方法。由于在表达式输入阶段已开始计算,因此计算结果的速度比静态确定法快。观察图5(a),当用户输入“+”时,已经可以开始计算“12*34”;观察图5(b),当用户输入“-”时,已经可以开始计算“34+56”;观察图5(c),当用户输入第一个“-”时,已经可以开始计算“12*21”。也就是说,当用户输入的运算符的优先级不大于前一个运算符时,即可开始前一个运算符的计算。问题是,对于有括号的运算表达式,在用户没有完成运算表达式的全部输入前,很难提前确定括号内部运算符的优先级。为了解决这个问题,动态确定法把优先符(括号)也赋予了优先级:n “(”,优先级为5;n “*、/”,优先级为4;n “+、-”,优先级为3;n “)”,优先级为1。计算图5三条运算表达式的所有符号的优先级别,结果如图7所示。图7运算符的动态优先级别设计计算的条件:(1) 只有优先级为3、4的符号(即+、-、*、/)可以进行计算;(2) 如果某符号的优先级大于等于下一个的优先级时,对此符号进行相应运算(当然每进行一次运算,相应的运算符即被消除,而参与运算的两个数值合并为一个数值);(3) 如果左右括号相邻,且左括号在右括号左边时(即在符号存储区里面出现“()”的情况,或者在优先级队列里出现“51”的情况),把这对括号消除掉。最后,当数值存储区里面剩下一个数值(或者符号存储区里面没有符号)时,运算结束,这个最后的数值就是运算的最终结果。请同学们自行设计此算法的流程图。5.3 结果输出当数值存储区里面剩下一个数值(或者符号存储区里面没有符号)时,运算结束,需要把运算结果输出显示。分析运算结果的特点:运算结果为一个2进制补码,整数,如果数据长度为16位,则运算结果范围是:-3276832767。运算结果的输出要解决的主要问题是:正负数区分、补码到ASCII码转换并输出显示。运算结果的输出流程如图8所示。图8 结果输出流程图5.3.1 正负数区分运算结果有三种情况:正整数、负整数、零。运算结果以补码形式对这三种情况进行统一的存储,但显示输出时则有所不同。负整数前面需要显示“-”号,因此需要对运算结果的符号进行判断。另一方面,正整数和零的补码与原码相同,而负整数的补码则不一样。把负整数进行取补码运算,把它转换为原码,可以实现运算结果统一的ASCII码转换输出方法,而不需要分别为正整数和零、负整数分别设计两个不同的ASCII码转换程序,如图9所示。图9 正负数区分流程图5.3.2 补码到ASCII码转换计算结果在屏幕上的输出显示实际上是ASCII码的输出显示。假设程序采用的数据长度为16位,则运算结果范围是:-3276832767,即屏幕最多得显示5位ASCII码。由于上文已经把结果统一为原码,下面介绍如何把原码转换为ASCII码。这个转换过程实际上跟上文的“数值的补码转换方法”是相反操作。例如要把123在屏幕上输出显示,即要把123的百位、十位、个位分离,得到1、2、3,然后转换为31H、32H、33H三个ASCII码。众所周知,把一位数转换为ASCII码只需加30H即可,下面介绍把一个多位数的各位分离的方法。(一)除十法分离方法是:对一个多位数进行除10处理,得到的余数即为个位数,而商则是删除个位后的多位数。对商反复进行除10处理,直到商为0为止,即可把各位数分离。例如对123进行除十法处理:123/10,商是12,余数是312/10,商是1,余数是21/10,商是0,余数是1可见经过三次除十计算,得到的三个余数刚好就是对123的各位的分离结果。接着只需分别对这些余数加30H即可转换为ASCII码,实现输出转换。除十法的优点是不需要理会要输出的数值有多少位,不断除以10直到商为0即可;缺点是得到的余数的顺序跟输出的方向相反,不方便输出。例如上例得到的三个余数的顺序是3、2、1,加30H转换输出后屏幕显示为“321”,跟期望显示的顺序相反,要作进一步处理。处理方法是把余数放进堆栈里面,然后再出栈显示。由于堆栈是先进后出的,即可解决该输出的顺序问题。图10 除十法流程图(二)除最高位法分离方法是先除以10位数-1,得到的商即为最高位,余数为删除最高位后的多位数。接着令余数除以10位数-2,得到的商为次高位,。例如123,其位数是3(个位、十位、百位),则计算过程为:123/103-1,商是1,余数是2323/103-2,商是2,余数是33/103-3,商是3,余数是0可见经过三次计算,得到的三个商刚好是对123的各位的分离结果,而且顺序跟输出方向相同。可以直接加30H转换输出,屏幕显示为“123”。该方法的缺点是:必须首先确定要输出的数值有多少位,编程者必须十分清楚需要输出的数值的数值范围。图11 除最高位法流程图6 得出的程序;-;-数据定义-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 exit ! *$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 ;将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: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 : 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 ;判断是数字还是符号JBE 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 FUH1 ;跳到判断优先级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 ;判断输入是否为=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 SI,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 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,BX 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 PUSH 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 DL,ALADD DL,30HMOV AH,2INT 21HMOV SI,1;-W4: MOV AX,BXMOV DX,0MOV BX,10DIV BXMOV BX,AXLOOP W2;- J_SHU1: MOV WORD PTRDI,0 CALL CR MOV NUMB,0 MOV SIGN1,0 LEA DI,NUMB ; LEA SI,MARK JMP STA1;-*返回DOS状态*- J_SHU: MOV AH,4CH;返回DOS状态INT 21H;-CSEG ENDSEND START7 心得体会 在这一周的课程设计中,我遇到了很多难题,由于在上一期并没有将微机原理学习好,导致我一开始看到这次课程设计题目时不知道应该如何下手,在通过翻看书本和上网找资料后,我渐渐的接触到一点眉目,开始进行尝试的编程,在不断的尝试、失败和修改中,我慢慢的懂得汇编一个计算器的基本原理和所需要的一些细节问题。最终,我经过翻找资料、询问同学并进行无数次的尝试后得出了我的程序。通过这次的课程设计,使我更加了解汇编语言的编写以及用途,让我反思上一学期的懒散,坚定自己努力学习的决心。14互联网2
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 成人自考


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!