目录
1 总体方案论证... 1
2 程序流程图及其说明... 3
2.1 程序流程图... 3
2.2 流程图说明... 5
3 软件设计... 5
3.1字符输入及存储设计... 5
3.2 加减法运算的判断设计... 6
3.3 加减法运算的设计... 7
3.3.1 数据的提取... 7
3.3.2 加法运算... 7
3.3.3 减法运算... 8
3.4 结果输出设计... 10
4 程序调试... 11
5 心得体会... 13
参考文献... 15
附录... 16
简易计算器汇编语言程序设计
该课程设计的任务是做一个简易计算器,可以对两个二位数进行加法和减法运算,例如11+23=34。我们平常的学习中做过给出两个数进行加减法运算的题目,但是这个题目难点在于这两个要做运算的数未知,是由自己调用中断输入到屏幕上并要用程序存储起来的数,然后才能对这两个二位数进行运算,而且做的是加法运算还是减法运算也未知,所以我们还要判断这个运算为加法运算还是减法运算。另外运算过程中的进位借位,选择什么方式进行输出,如何实现清屏等也是要解决的问题。
首先我们要解决的是输入时是用INT 21H的10号功能调用还是用INT 21H的1号功能调用来进行输入。若是用10号功能调用则我们进行多字符输入,可以将输入的字符都存储到一个数据区里面,并调用9号功能调用输出存进去的字符,这种输入和输出的方案是可行的。我选择的是利用1号功能调用来输入,即把单个字符一个个的输入并存储到一个数据区里。我们要做的是两个二位数的运算,先认定输入的格式为ab+cd=或者ab-cd=,当然如果输入不是这样的格式计算出来的结果就不一定是我们想要的结果了。在存储的时候也是有选择的存储,当输入的并非格式里所要求的字符时则报错。
然后我们要判断是做加法运算还是减法运算,即判断输入的运算符是‘+’号还是‘-’号,因为输入的格式固定了,所以只需要把存进数据区的第三个字符拿来和‘+’号进行比较,若相等则进行加法运算,若不等则为减法运算。
在进行运算的过程中会想到到底如何对存进数据区的数据进行提取来作运算,一种方案是将‘+’号或‘-’号之前的两位数提取出来,当然要做一个10a+b的换算,同理将后两位按照这种方式提取出来,最后进行运算。因为考虑到这种方式在运算时个位或十位进位或者借位的情形比较麻烦,所以我想到了把两个二位数的十位提取出来进行运算存到一个数据区里,个位也同时提取出来进行运算并存到该数据区,在这里把十位和个位拆开来进行运算再考虑进借位时就方便些,并且输出的时候也比较方便。大致地数据提取和运算如图1所示
图1 数据的提取运算示意图
由于运算过程中出现的进借位问题,会导致输出的结果为一位数,二位数,三位数或者是负数,所以在选择输出的方式时若是选9号功能调用会很不方便,因为9号功能调用要求有一个输出字符的缓冲区,由于输出的结果形式太多,缓冲区太难确定,而且若结果为负数,负号也得事先进行设置,所以单字符输出是一个合理的选择。
最后还要对这个简易计算器进行功能完善,例如为了使程序符合我们使用者的操作习惯,我们可以添加按回车键换行输入,即当键入回车键后,可以换行重新输入;可以设置按C或c键清屏,当键入C或c键时,清除整个屏幕上的输入和输出的字符并可以重新输入并运算;当按下Q或q键退出程。
该程序流程图简要地表现出了所要实现的功能以及一些功能的大概算法,同时也是我编写的程序的一个总体的框架。
通过流程图,可以看出程序开始运行时,首先输出提示语句,再输入字符,并判断输入的字符是否为Q或q,若是,则退出,不是则继续输入;判断输入的字符是否为C或c,若是,则清屏重新输入,否则继续输入;判断输入的是不是回车键,若是就回车换行输入,不是则继续输入;判断输入的是否为0~9,+,-,=这些字符,若不是会报错,是则将其存储到定义的数据区BUFF里面,再判断如果输入的不是=功能键,则继续输入,若是,则判断是做加法运算还是减法运算,最后输出结果,并重新输入,继续上面的步骤。
利用INT 21H的1号中断一个一个地输入字符,并将输入地字符和Q,q比较,若相等则退出程序,不等则与C,c 比较,如果相等则清屏并重新输入,不等就判断输入的字符是否为0DH即回车键对应的ASCII码值,再看输入的是否为0~9,+,-,=这几个字符,若是则存储,若不是就在屏幕上输出错误提示,程序如下:
START1: MOV AH,1 ;输入字符
INT 21H
CMP AL,'Q' ;输入为Q或q时退出程序
JZ EXIT
CMP AL, 'q'
JZ EXIT
CMP AL,'C' ;输入为C或c时清屏
JZ QINGPING
CMP AL,'c'
JZ QINGPING
CMP AL,0DH ;输入回车键时,换行重新输入
JZ HUANHANG
CMP AL,'+' ;输入的字符不为+,-,=,0到9的字符时则报错,并重新换行输入,是则存储
JNZ LOOP1
JMP CUNCHU
LOOP1:
CMP AL,'-'
JNZ LOOP3
JMP CUNCHU
LOOP2:
CMP AL,'0'
JB ERROR
CMP AL,'9'
JA ERROR
SUB AL,30H
JMP CUNCHU
LOOP3:
CMP AL,'='
JZ LOOP4
JMP LOOP2
由于输入字符的格式固定为两位数加两位数的格式,则只需把存在BUF数据区的第三个字符提出来并与加号的ASCII码值进行比较即可判断为加法过算还是减法运算了,若相等则为加法过算不等则为减法运算,具体程序实现如下:
PANDUAN: ;判断为加法还是减法运算
CMP BYTE PTR[BX+2], '+'
JZ JIAFA ;结果为零则为加法运算
JMP JIANFA ;结果不为零则为减法运算
可以将两个数的十位数提取出来作运算并存储到一个数据区里,然后将两个数的个位数提取出来作运算存储到该数据区,如下程序段落所示为把两数的十位数分别取出
LEA BX,BUF
MOV DL,BYTE PTR[BX] ;提取两个数的十位的数据
MOV AL,BYTE PTR[BX+3]
同理,把两个数的个位数提取出来,如下
MOV DL,BYTE PTR[BX+1] ;提取两个数的个位的数据
MOV AL,BYTE PTR[BX+4]
判断为加法运算并分别提取加数和被加数个位数和十位数之后,就要进行运算了,因为要虑到运算过程中的进位,如个位进位以及十位进位,还要考虑到结果为两位数或三位数的输出情况,所以在运算时要分别判断个位是否进位,进位则进行个位进位调整,十位是否进位,进位则进行十位进位调整。具体程序实现如下:
JIAFA: LEA BX,BUF
MOV DL,BYTE PTR[BX+1]
MOV AL,BYTE PTR[BX+4]
ADD AL,DL
CMP AL,10
JAE TZ1
ADD AL,30H
MOV [SI+1], AL
MOV DL, BYTE PTR[BX]
MOV AL,BYTE PTR[BX+3]
JMP BACK1
BACK1: ADC AL,DL
CMP AL,10
JAE TZ10
ADD AL,30H
MOV [SI], AL
JC DATA3
JMP DATA2
BACK10:
MOV [SI], AL
JC DATA3
JMP DATA2
TZ10: SUB AL,10 ;十位相加有进位的处理
ADD AL,30H
STC
JMP BACK10
TZ1: SUB AL,10 ;个位相加有进位的处理
ADD AL,30H
MOV [SI+1] ,AL
MOV DL, BYTE PTR[BX]
MOV AL,BYTE PTR[BX+3]
INC AL
JMP BACK1
判断为减法运算并分别提取减数和被减数个位数和十位数之后,就要进行减法运算了,减法运算时比较复杂,要考虑个位的借位,十位的借位,以及结果为正数时两位数和一位数结果的输出同时还要考虑到结果为负数时输出,结果为一位数的负数输出和结果为两位数的负数输出几种情况。首先我们将减数和被 减数的十位进行比较,如果减数的十位数字大于被减数的十位数则结果为正数,若小于则为负数,若相等再比较个位数的大小,在结果为正数的情况下考虑输出为一位数还是两位数,若有借位则进行相应的调整;在结果为负数的情况下,考虑输出为一位数还是两位数,同样要对产生借位的进行处理;若十位数相等则考虑输出结果为零或正的一位数及负的一位数。具体的程序如下:
JIANFA: LEA BX,BUF
MOV DL,BYTE PTR[BX] ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
CMP AL,DL
JZ COMP1
JA FU
JMP ZHENG
ZHENG: LEA SI,JIEGUO ;结果为正数的运算
LEA BX,BUF
MOV DL,BYTE PTR[BX+1 ;提取被减数和减数个位的数据
MOV AL,BYTE PTR[BX+4]
CMP DL,AL
JB JIEWEI1
SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX] ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
JMP SUB1
SUB1: SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI], AL
CMP AL,0
JZ DATA1
JMP DATA2
JIEWEI1: ;借位处理
ADD DL,10
SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
SUB DL,1
JMP SUB1
COMP1: LEA SI,JIEGUO
LEA BX,BUF
MOV DL,BYTE PTR[BX+1]
MOV AL,BYTE PTR[BX+4]
CMP AL,DL
JZ ZERO
JA FU1
JB ZHENG1
ZHENG1: SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI+1], AL
JMP DATA1
FU1: SUB AL,DL
ADD AL,30H
MOV [SI+1], AL
JMP FUSHU1
FU: LEA SI,JIEGUO ;结果为负数的运算
LEA BX,BUF
MOV DL,BYTE PTR[BX+1]
MOV AL,BYTE PTR[BX+4]
CMP AL,DL
JB FU_1
SUB AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX]
MOV AL,BYTE PTR[BX+3]
SUB2: SUB AL,DL
ADD AL,30H
MOV [SI], AL
CMP AL,30H
JZ FUSHU1
JMP FUSHU2
FU_1: ;借位处理
ADD AL,10
SUB AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
SUB AL,1
JMP SUB2
最终结果的输出采用的是INT 21H的9号功能调用,考虑到输出结果的形式很复杂,所以对于输出的结果分了好几种情况,例如结果为正数时的一位,二位,三位数的输出,结果为负数时的一位,二位输出以及零的输出几种情况,尤其是对于三位数的输出和负数的输出,可以分别在结果前面直接加一个‘1’和一个‘-’号。具体的程序见附录
运行程序后,进入程序运行初始界面,会有一个作两位数加减法运算,输入等号后才输出结果的提示语句,如图1
图1 程序运行初始界面
不是0~9,+,-,=号时,例如输入一个w,程序会有报错提示,并提示重新输入,运行界面如图2所示
图2 出错并重新运行界面
当两个数运算无进位和借位时,一共有三种可能的情况,作加法运算时个位和十位均无进位,以及减法过算时个位和十位均无借位且输出为一位数和两位数的情况,运行结果如图3所示
图3 没有进借位的运行界面
经检验,这三种可能情况下的所有运行结果都正确
当两个数运算个位有进借位时,其运行情况如图4所示,有加法和减法运算个位进借位的两种情况。
图4 个位有进借位的运行界面
经检验运行后程序输出的结果正确
当两个数运算十位有进借位时,若是加法运算即结果一定是三位数,且百位为1的情况,加是减法运算,则分输也为一位和两位的两种情况,程序的运行界面如图5
图5 十位有进借位的运行界面
经检验运行后程序输出的结果正确
当两个数运算个位和十位均有进借位时一共有如下三种情形,其运行界面如图6所示
图6 个位和十位均有进借位的运行界面
经检验所有输出结果都正确
当输入C或c时则清屏,程序运行后清除整个窗口内输入和输出的字符并可以继续输入并计算。如图7所示
图7 清屏后的运行界面
经调试,基本上任务要求设计的所有功能都实现,调试出的计算结果均正确
两周的课程设计结束了,给我的总体感觉就是忙碌但充实,而且真正学到了东西。
以前做课程课计的时候总是前几天时间玩,后面几天才开始做,不过这次却是一直都在做这个课程设计,因为在网上我根本搜不到别人写的简易计算机的资料,所以从构思到设计流程图到编写源程序都是我一个人独立完成的,虽然这个过程比较痛苦,但是我真正的去体验了,当我编写的程序一遍一遍地报错,出的结果一次次和正确结果有出入的时候我真的好想放弃,但是我选择了坚持,通过调试程序,一步步地看寄存器和数据区的变化,最终发现了错误并改正了错误,当运行的结果全都正确的时候我真的好激动,好有成就感,因为这是我第一次自己独立地编写的长达两百多条的程序,虽然结构看上去有点乱,语句不够精练,但是不管怎样,我终于能够实现要求的功能了。
这次虽然在网上没有搜到什么资料,但是我还是学会了更好地利用资源——身边的高手,研究生学长,还有课本。身边的高手以及学长都在我编程的过程中给了我很多很好的建议,让我在山重水复疑无路时,突然柳暗花明又一村。而书本是我最好的帮手,有任何编程细节不太清楚的,我就去翻书,一般都能在书中找到答案,所以我认为万变不离其宗这句话是很正确的,不管老师给我们的任务如何难或复杂,也都是由书本上介绍的一条条简单的程序构成的,例如我的程序虽然长,有两百多条语句,但是却可以将其拆分成多个小块,每个小块其实都是一个最基础的小程序,并能实现一个功能,最后组合起来就实现了任务要求的比较复杂的功能了。
另外,这次无论是设计个这程序还是写课程设计报告都让我学到了好多东西,有对课本知识更加深入的了解和掌握,也有对于流程图的设计以及绘制还有word的一些用法和排版等,都让我受益匪浅,
总之,非常感谢学校和老师给我们安排了这次课程设计,不仅让我掌握了更多的知识,还让我领会到要把一件事情做好并真正有所收获还得靠自己独立地去完成并坚持不懈!希望在以后的学习中还能多搞几次这种课程设计。
[1] 周佩玲、彭虎、傅忠谦.微机原理与接口技术(基于16位机). 北京:电子工业出版社.,2005
[2] 马春燕.微机原理与接口技术(基于32位机)实验与学习辅导. 北京:电子工业出版社.,2007
[3] 何小海、严华. 微机原理与接口技术.北京:科学出版社,2006
[4] 钱晓捷. 新版汇编语言程序设计. 北京:电子工业出版社,2007
完整的程序代码如下:
DATA SEGMENT
BUFF DB 6 DUP(?)
JIEGUO DB 3 DUP(?)
COUNT EQU 6
TISHI DB 'The addition and subtraction operations of two two-digit',0DH,0AH,'Input "=",then output the result:',0DH,0AH,'$'
ERROR1 DB 0DH,0AH,'Input error!',0DH,0AH,'Please input again!',0DH,0AH,'$'
HUICHE DB 0DH,0AH,'$'
TUICHU DB 'Please press any key to continue!','$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
LEA DX,TISHI
MOV AH,9
INT 21H
LEA SI,JIEGUO
LEA BX,BUFF
START1: MOV AH,1
INT 21H
CMP AL,'Q' ;输入为Q或q时退出程序
JZ EXIT
CMP AL, 'q'
JZ EXIT
CMP AL,'C' ;输入为C或c时清屏
JZ QINGPING
CMP AL,'c'
JZ QINGPING
CMP AL,0DH ;输入回车键换行重新输入
JZ HUANHANG
CMP AL,'+' ;输入的字符不为+,-,=,0到9的字符时,则报错,并重新换行输入,是则存储
JNZ LOOP1
JMP CUNCHU
HUANHANG: LEA DX, HUICHE ;实现换行的功能
MOV AH,9
INT 21H
JMP START1
ERROR: LEA DX,ERROR1
MOV AH,9
INT 21H
JMP START1
CUNCHU: ;对输入的字符进行存储
MOV [BX],AL
INC BX
JMP START1
LOOP1:
CMP AL,'-'
JNZ LOOP3
JMP CUNCHU
LOOP2:
CMP AL,'0'
JB ERROR
CMP AL,'9'
JA ERROR
SUB AL,30H
JMP CUNCHU
LOOP3:
CMP AL,'='
JZ LOOP4
JMP LOOP2
LOOP4: ;判断为加法还是减法运算
XOR BX,BX
LEA BX,BUFF
MOV CX,COUNT
PANDUAN:
CMP BYTE PTR[BX+2], '+'
JZ JIAFA
JMP JIANFA
JIAFA: LEA BX,BUFF
MOV DL,BYTE PTR[BX+1] ;提取两个加数个位的数据
MOV AL,BYTE PTR[BX+4]
ADD AL,DL
CMP AL,10
JAE TZ1
ADD AL,30H
MOV [SI+1], AL
MOV DL, BYTE PTR[BX] ;提取两个加数十位的数据
MOV AL,BYTE PTR[BX+3]
JMP BACK1
BACK1: ADC AL,DL
CMP AL,10
JAE TZ10
ADD AL,30H
MOV [SI], AL
JC DATA3
JMP DATA2
BACK10:
MOV [SI], AL
JC DATA3
JMP DATA2
TZ10: SUB AL,10 ;十位相加有进位的处理
ADD AL,30H
STC
JMP BACK10
TZ1: SUB AL,10 ;个位相加有进位的处理
ADD AL,30H
MOV [SI+1] ,AL
MOV DL, BYTE PTR[BX]
MOV AL,BYTE PTR[BX+3]
INC AL
JMP BACK1
JIANFA: LEA BX,BUFF
MOV DL,BYTE PTR[BX] ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
CMP AL,DL
JZ COMP1
JA FU
JMP ZHENG
ZHENG: LEA SI,JIEGUO ;结果为正数的运算
LEA BX,BUFF
MOV DL,BYTE PTR[BX+1] ;提取被减数和减数个位的数据
MOV AL,BYTE PTR[BX+4]
CMP DL,AL
JB JIEWEI1
SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX] ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
JMP SUB1
SUB1: SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI], AL
CMP AL,0
JZ DATA1
JMP DATA2
JIEWEI1: ;借位处理
ADD DL,10
SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX] ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
SUB DL,1
JMP SUB1
COMP1: LEA SI,JIEGUO
LEA BX,BUFF
MOV DL,BYTE PTR[BX+1]
MOV AL,BYTE PTR[BX+4]
CMP AL,DL
JZ ZERO
JA FU1
JB ZHENG1
ZHENG1: SUB DL,AL
MOV AL,DL
ADD AL,30H
MOV [SI+1], AL
JMP DATA1
FU1: SUB AL,DL
ADD AL,30H
MOV [SI+1], AL
JMP FUSHU1
FU: LEA SI,JIEGUO ;结果为负数的运算
LEA BX,BUFF
MOV DL,BYTE PTR[BX+1]
MOV AL,BYTE PTR[BX+4]
CMP AL,DL
JB FU_1
SUB AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX]
MOV AL,BYTE PTR[BX+3]
SUB2: SUB AL,DL
ADD AL,30H
MOV [SI], AL
CMP AL,30H
JZ FUSHU1
JMP FUSHU2
FU_1: ADD AL,10 ;借位处理
SUB AL,DL
ADD AL,30H
MOV [SI+1], AL
MOV DL,BYTE PTR[BX] ;提取被减数和减数十位的数据
MOV AL,BYTE PTR[BX+3]
SUB AL,1
JMP SUB2
AA PROC NEAR ;输出两位数的子程序
LEA SI,JIEGUO
MOV DL,[SI]
MOV AH,2
INT 21H
MOV DL,[SI+1]
MOV AH,2
INT 21H
JMP START1
RET
AA ENDP
ZERO: MOV DL, 30H ;结果为0的输出
MOV AH,2
INT 21H
JMP START1
DATA1: LEA SI,JIEGUO ;一位数的输出(如13-12=1)
MOV DL,[SI+1]
MOV AH,2
INT 21H
JMP START1
DATA2: CALL AA ;两位数的输出(如32-14=18或18+14=32)
DATA3: MOV DL,31H ;三位数的输出 (如89+77=166)
MOV AH,2
INT 21H
CALL AA
FUSHU1: MOV DL,'-' ;结果为一位数的负数的输出 (如13-22=-9)
MOV AH,2
INT 21H
LEA SI,JIEGUO
MOV DL,[SI+1]
MOV AH,2
INT 21H
JMP START1
FUSHU2: MOV DL,'-' ;结果为两位数的负数的输出 (如23-45=-22)
MOV AH,2
INT 21H
CALL AA
QINGPING: MOV AL,0 ;实现清屏功能
MOV BH,7
MOV CH,0
MOV CL,0
MOV DH,24H
MOV DL, 79H
MOV AH,6
INT 10H
MOV DX,0
MOV AH,2
INT 10H
JMP START1
EXIT: LEA DX,TUICHU ;退出程序
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
东莞理工学院《C语言程序设计》课程设计题目:图书信息管理系统院系:电子工程学院专业:电子信息工程年级:20##班别:2班指导教师:…
C语言程序设计课程设计学生姓名学号系院专业设计论文题目学生选课系统管理完成日期20xx年6月指导教师目录一实验目的二实验内容三总体…
河南理工大学计算机科学与技术学院课程设计报告20XX20XX学年第一学期课程名称C语言课程设计设计题目《小学算术运算测试》学生姓名…
C语言课程设计报告设计题目专业班级学号姓名任课老师时间目录一课程设计题目及所涉及知识点二课程设计思路及设计流程图三课程设计中遇到的…
C语言程序设计课程设计报告20xx20xx学年第1学期题目专业班级姓名学号指导教师成绩计算机科学与技术系20xx年12月31日目录…
实验七分支程序实验目的1掌握利用间接转移指令JMPBX实现多岔分枝的方法2宏替换指令MACRO及ENDM3符号扩展指令CBW实验程…
计算机组成原理与汇编语言实验20xx指导教师签名一实验原理基本知识简单介绍算法流程计算机组成原理与汇编语言实验20xx计算机组成原…
实验六汇编语言程序上机过程实验目的1掌握常用工具软件PEMASM和LINK的使用2伪指令SEGMENTENDSASSUMEENDO…
学生实验报告册20xx20xx学年第1学期实验名称汇编语言程序设计学院信息与电气工程学院班级09级计算机科学与技术2班学号1351…
武汉理工大学华夏学院课程设计报告书课程名称:汇编语言课程设计题目:等腰三角形的输出系名:信息工程系专业班级:计算机1102姓名:学…