微机原理及接口技术
课程设计
题目 学院 专业 班级 姓名 指导教师
加减乘除四则运算程序
自动化学院 电气工程及其自动化
电气1204 李铭昕 李道远
2014 年 12 月 30 日
课程设计任务书
学生姓名: 李铭昕 专业班级: 电气1204班 指导教师: 李道远 工作单位: 自动化学院
题 目: 加减乘除四则运算程序 初始条件:
从键盘接受16进制数四则运算表达式。能实现加、减、乘、除的计算。执行时,需在显示屏上显示计算表达式并给出计算结果。按Q退出程序。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
(1) 设计任务及要求分析 (2) 方案比较及认证说明 (3) 系统原理阐述 (4) 硬件设计课题需要说明:硬件原理,电路图,采用器件的功能
说明 (5) 软件设计课题需要说明:软件思想,流程图,源程序及程序注
释 (6) 调试记录及结果分析 (7) 总结 (8) 参考资料 (9) 附录:芯片资料或程序清单,软件演示屏幕拷贝图或硬件
目录
1.概述 ................................................................ 5 1.1 设计任务 ........................................................... 5
1.2 设计功能 ...................................................................................................5 1.3 开发环境 ...................................................................................................5 2.程序设计 ............................................................ 5
2.1程序模块 ...................................................................................................5 2.2 主要算法 ...................................................................................................6 2.2.1 运算类型选择算法 ............................................................................6 2.2.2 字符输入算法 ....................................................................................7 2.2.3 四则运算算法 ....................................................................................8 2.2.4 输出算法 ..............................................................................................8 2.3 程序流程图 ..............................................................................................9 3 程序调试 ............................................................ 10
3.1.1 操作步骤 ............................................................................................10 3.1.2程序调试 .............................................................................................10 4 小结 ................................................................ 12 参考文献 .............................................................. 13 附录 .................................................................. 14 附录源程序清单 ........................................................ 14
摘要
在汇编语言程序设计时常用到四则运算,而汇编语言是低级语言,用它来实现四则运算较为困难。本次设计利用Emu8086集成环境以及各种指令来实现输入十六进制的加减乘除运算,同时在屏幕上显示计算表达式,结果以十六进制输出。汇编语言虽然没有高级语言一样具有较高的可读性,但是由于汇编语言是一种机器语言,所以它的效率要比高级语言高得多。此次设计主要通过课程设计深入了解语言的特点是用符号代替了机器指令代码,而且助记符与指令代码一一对应,基本保留了机器语言的灵活性。使用汇编语言能面向机器并较好地发挥机器的特性,得到质量较高的程序。
关键词:四则运算;算法选择;数制转换
加减乘除四则运算程序
1.概述
1.1 设计任务
本次设计要求系统可实现从键盘接受十六进制数的四则运算表达式,可以实现加减乘除四则运算并在屏幕上显示计算结果,按Q退出程序。
1.2 设计功能
本程序输入的两个数字最大为FFFF,两个数分别给BX和[SI],以便运算。程序执行前,先选择运算类型,如果输入字符不属于运算类型的一种,则显示错误。选择好运算类型后,输入数字。程序中规定数字的输入只能是0至9、A至F或a至f之间,超出此范围显示错误,重新输入。按Q选择退出程序,并按Y确认退出。
1.3 开发环境
Emu8086
2.程序设计
2.1程序模块
本程序分为三大模块,如图2-1所示。主要包括:
1.界面设置。主要实现确定界面样式的功能,并且提示该如何操作,以菜单形式显示。
2.选择算法设置。用+、-、*、/分别表示加、减、乘、除四种运算,通过输入符号来选择运算类型。
3.十六进制转换设置。无论是输入还是输出,都是以十六进制数表示的。而调用DOS输入或输出的则是字符的ASCII码值,所以数据输入输出是必有一个数据类型转换的过程。输入时,将输入字符的ASCII码转换成相应的十六进制数,并以此参与运算,输出时,以四位二进制数为一个单位转换成十六进制数相对应的ASCII码调用DOS输出即可得十六进制数的计算结果。
2.2 主要算法
2.2.1 运算类型选择算法
通过DOS调用输入运算加减乘除的符号,再用CMP指令使输入的运算符号与‘+’、‘-’、‘*’、‘/’依次比较,看输入的字符与那种运算符号相等从而确定运算的类型并提示输入数据。如果输入的字符不属于上述的四种符号会显示输入错误并提示重新输入。输入正确和错误的情况分别入图3-1和图3-2所示。
图2-1 程序模块
图3-1 运算符号输入正确时程序运行情况
图3-2 运算符号输入错误时程序运行情况
2.2.2 字符输入算法
调用DOS输入字符时,首先判断输入的字符是否为回车键,是回车键则退出。然后用CMP指令判断AL中的字符是否小于‘0’,小于则显示输入数据错误并提示重新输入数据。如果AL中的数字大于等于‘0’,在判断其是否小于等于‘9’,是的话,将AL中的数减去30H,得到相应的十六进制数。如果大于‘9’,则判断AL中的数是否小于‘A’,是的话则显示输入错误,提示重新输入数据。如果大于等于‘A’则判断其是否小于等于‘F’,是的话将AL中的数减去37H,得到相对应的十六进制数。如果大于‘F’,则和‘a’比较,如果小于‘a’则显示输入错误,并提示重新输入数据,如果大于等于‘a’,则和‘f’比较,如果小于等于‘f’则将AL中的数先减去20H再减去37H,得到其对应的十六进制数。输完数据后,程序跳转到数据保存的程序段中。
输入的数据放置于BX中,由于四位二进制数代表一位十六进制数,所以存入数据时,先将BX中的数据左移四位,然后将BX与AL相加所得结果放在BX中,这样可以保证输入的高位在BX的高位,输入的低位在BX的低位。保存完数据后程序会自动跳回数据输入程序。数据输入正确或错误时的程序执行情况如图3-3和图3-4所示。
图3-3 数据输入正确时程序运行情况
图3-4 数据输入错误时程序运行情况
2.2.3 四则运算算法
(1)加法。先输入第一个小于4位的十六进制数存入SI中并将SI中的数给DX,再输入第二个小于4位的十六进制数存入BX中。执行加法时,先用ADD指令将DL和BL中的数相加,所得的和放在BL中,然后用ADC指令执行DX和BX高八位的相加,这样可以考虑低八位产生的进位。
(2)减法:先输入第一个小于4位的十六进制数存入SI中,再输入第二个小于4位的十六进制数存入BX中,然后BX和[SI]中的内容相减存入BX中,再用NEG求反,即为第一个数减去第二个数的差,当结果为负数的时候,其值为补码。 (3)乘法:先输入第一个小于4位的十六进制数存入SI中,再输入第二个数存入BX中,把BX的值给AX,然后让AX乘以[SI],所得的数可能为32位的二进制数,这时,若要显示结果则需要分别将DX、AX中的内容赋给BX,接着依次显示DX、AX的内容,即为积。
(4)除法:先输入第一个小于4位十六进制数存入SI中,再输入第二个数存入BX中,将[SI]赋给AX作被除数,并且应该将DX清零以满足除法指令32位除以16位的要求,再让BX作除数,得到的商存放在AX中,余数放在DX中,然后依次赋给BX,将其依次显示即为商。
2.2.4 输出算法
字符输出同样是调用DOS功能。由于输出的运算结果确定是正确的十六进制数值,所以输出时不必像输入时那样去检测字符是否错误,只需将要输出的十六进制数码转换成相应的ASCII码值并注意输出顺序正确即可。具体的操作步骤如下:首先用ROL指令将BX中最高四位移到BL中,再将BL的数给DL,用AND指令将DL高四位清零,然后将DL中的数加30H,再判断此时的数是否大于39H,若不大于,说明该十六进制数在0至9之间,调用DOS输出即可。若DL中的数大于39H,则说明该十六进制数在A至F之间,这个时候,再给DL中的数加7H然后输出即可。由于BX有十六位二进制数,所以执行以上步骤四次就可以输出运算结果,执行次数通过CH控制,首先给CH赋值为4,没执行一次CH的数减一直至CH等于0。
2.3 程序流程图
图3-5 程序流程图
流程图如上所示,选择运算符时和‘+’、‘-’、‘*’、‘/’依此比较,相符则进行相应的运算,不符合则看输入是否为Q,不是的话则说明输入错误,提示出错,是Q则在此通过Y/N选择,Y为确定退出,N则返回重新输入。
3 程序调试
3.1.1 操作步骤
操作步骤如下:
1.按提示选择运算类别: +:加法 -:减法 *:乘法 /:除法
2.按提示输入一个不高于四位的十六进制数 3.再输入一个不高于四位的十六进制数 4.显示计算结果 5.按Q选择Y/N
3.1.2程序调试
加法:算法选择‘+’,按提示输入两个十六进制数,回车后显示计算式 和结果。程序运行截图如图3-1所示。
图3-1 加法程序截图
减法:算法选择‘-’,按提示输入两个十六进制数,回车后显示计算式和 结果,若结果为负数,则屏幕上结果显示为补码。程序运行截图如图3-2所示。结果为负数的程序运行截图如图3-3所示。
图3-2 结果为正数的减法
图3-3 结果为负数的减法
乘法:算法选择‘*’,按提示输入两个十六进制数,回车后显示计算式和结果。程序运行截图如图3-4所示。
图3-4 乘法程序截图
除法:算法选择‘/’,按提示出入两个十六进制数,回车后显示计算式和结果,结果包括商和余数。程序截图如图3-5所示。
图3-5 除法程序截图
退出程序:按Q,选择Y即可退出程序。程序截图如图3-6所示。
图3-6 退出程序部分截图
4 小结
本次十六进制四则运算的程序设计,对于我来说还是有一定难度的,因为用汇编语言来实现四则运算并没有高级语言来得简单,所以在写程序的时候也遇到了一些困难,特别是输入输出数据的时候要用程序实现数据转移到BX的时候,很容易搞混顺序,造成结果错误。但是经过一系列的调试后,这些问题都解决了。在调试的过程中也加深了我对8086指令系统的认识。本次的程序总的来说还是比较好的满足了设计的要求,但也有不足,比如,当输入超过了四位没有提醒以及结果溢出也无警示,这些都是有待改进的地方
参考文献
[1]刘其明.《汇编语言程序设计教程》.徐州:中国矿业大学出版社,2010.11 [2]竺士蒙、李可.《汇编语言程序设计》.北京:清华大学出版社.2006 [3]谢宋和、甘勇.《单片机模糊控制系统设计与应用实例[M]》.北京:电子工业出版社,1999
[4]王爽.《汇编语言》.北京:清华大学出版社.2003
[5]齐志儒、高福祥.《汇编语言程序设计[M]》.北京:北京大学出版社.2007 [6]沈美明、温冬婵编著《IBM—PC汇编语言程序设计(第二版)》.北京:清华大学出版社.2005
[7]彭虎、周佩玲、傅忠谦.《微机原理与接口技术(第三版)》.电子工业出版社.2011
附录
附录源程序清单
IN16 MACRO ;完成从键盘接受二个数并转换为十六制数,第一个数由
SI指向,第二个数存放在BX中
LEA DX,PR ;DX指向PR换行 CALL OUTPUT ;
LEA DX,INPUT1 ;DX指向INPUT1,提示输入第一个数 CALL OUTPUT
CALL INPUT ;把输入的数存放在BX中 LEA SI,RESULT ;SI指向RESULT
MOV [SI],BX ;把第一个十六制数存入RESULT的第一个位置 LEA DX,PR ;DX指向PR,换行 CALL OUTPUT
LEA DX,INPUT2 ;DX指向INPUT2,提示输入第一个数 CALL OUTPUT
CALL INPUT ;把输入的数存放在BX中 ENDM ;宏结束 DATA SEGMENT ;数据段 BUF DB ' ',0DH,0AH
DB '*------- WELCOME TO CALCULATOR SYSTEM ---------*',0DH,0AH
DB'*---‘+’:ADD--‘-’:SUB--‘*’:MUL--‘/’:DIV--Q:QUIT---------*'
,0DH,0AH
DB '*---------- 2014*12*31---------------*',0DH,0AH DB '*----------- Made by LMX--------*',0DH,0AH DB 0DH,0AH,'Please input the choose number:','$'
INPUT1 DB 'Please input the first number xiao yu 4 wei:','$' INPUT2 DB 'Please input the second number xiao yu 4 wei:','$' RESULT DW ?,? ;存放键盘输入的两个十六制数
WRO DB 'You input the number is wrong,please input again:',0DH,0AH,'$'; PR DB 0DH,0AH,'$' ;将光标移到下一行起始位置 PR1 DB 'A + B=$' PR2 DB 'A - B=$' PR3 DB 'A * B=$' PR4 DB 'A / B=$' PR5 DB '......$'
PR6 DB 'Are you sure exit?(Y/N)$' DATA ENDS ;数据段落定义结束 CODE SEGMENT
MAIN PROC FAR ;主函数 ASSUME CS:CODE ,DS:DATA START:
MOV AX,DATA MOV DS,AX
LEA DX,BUF ;DX指向BUF换行
CALL OUTPUT ;调用显示字符串函数换行 SUB AX,AX ;AX清零
CALL CHOOSE ;调用选择函数 JMP START ;跳转到START RET MAIN ENDP
INPUT PROC NEAR ;定义INPUT函数,就是将从键盘输入的数按原十六进制数
MOV BX,0 ;BXNEWCHAR:
MOV AH,1
INT 21H ;CMP AL,0DH ;JE EXIT
CMP AL,'0' ;JB CALL WRONG
CMP AL,'9' ;JBE H1 ;CMP AL,'A' ;JB CALL WRONG ;CMP AL,'F' ;JBE H0 ;CMP AL,'a' ;JB CALL WRONG ;CMP AL,'f' ;JBE H2 ;CALL WRONG ;H2:SUB AL,20H ;H0:SUB AL,37H ;JMP ADDTO ;H1:SUB AL,30H ;JMP ADDTO ;ADDTO:
MOV CL,4 ;SHL BX,CL ;MOV AH,0 ;ADD BX,AX ;AX+BX
JMP NEWCHAR ;EXIT: RET INPUT ENDP
OUTPUT PROC NEAR ;MOV AH,09H
存放在BX中
清零 接受键盘输入一个字符 输入与回车比较,是就结束 输入与0比较,小于则显示错误 大于0则和9比较
小于等于9则转换为对应的十六进制数 大于9则和A比较 小于A则显示错误 大于等于A则和F比较
小于等于F则将其转换为对应的十六进制数 大于F则和a比较 小于a则显示错误 大于a则和f比较
小于等于f则转换为对应的十六进制数 否则显示错误
若是a-f,则应该先减20H
由于41-A=37,完成把字母字符转换成对应的十六进制数 跳转到ADDTO
把0到9的字符转换成对应的十六进制数 跳转到ADDTO 相当于让BX乘以16 将BX逻辑左移 将AX清零 送到BX 跳转到NEWCHAR,把第二个输入的字符存放到BX的第二位 显示字符串函数
INT 21H RET
OUTPUT ENDP
CHOOSE PROC NEAR ;选择函数
MOV AH,1 ;从键盘接受一个数 INT 21H
CMP AL,'+' ;与+比较
JE YES1 ;等于+就跳转到YES1,进行加法 CMP AL,'-' ;与-比较
JE YES2 ;CMP AL,'*' ;JE YES3 ;CMP AL,'/' ;JE YES4 ;CMP AL,'Q' ;JE EXIT1 ;CALL WRONG ;EXIT1: LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR6 ;DXCALL OUTPUT
MOV AH,1 ;INT 21H
CMP AL,'Y' ;JE EXIT0 ;CMP AL,'y' ;JNE START ;EXIT0:MOV AH,4CH ;INT 21H
YES1:CALL JIA ;JMP START ;YES2:CALL JIAN ;JMP START ;YES3:CALL CHENG ;JMP START ;YES4:CALL CHU ;RET
CHOOSE ENDP ;WRONG PROC NEAR ;LEA DX,PR ;DXLEA DX,WRO ;DXJMP START ;RET
WRONG ENDP ;等于-就跳转到YES2,进行减法 与*比较
等于*就跳转到YES2,进行乘法 与/比较
等于/就跳转到YES2,进行除法 与Q比较
等于Q就跳转到EXIT1,结束程序 如果以上的数就提示出错 指向PR换行 指向PR6,确认是否退出 从键盘接受一个数 与Y比较
不是Y就看是否为y 与y比较
不是y就跳转到START 结束本程序 调用JIA函数
调用完之后跳转到START 调用JIAN函数
调用完之后跳转到START 调用CHENG函数
调用完之后跳转到START 调用CHU函数 选择函数结束 报错函数
指向PR换行
指向WRO,提示输入有错,请重新输入跳转到START 报错函数结束
JIA PROC NEAR ;加法函数
IN16 ;调用宏,接受键盘输入的两个十六进制数,第一个数由SI
指向,第二个数存放在BX中
MOV CX,[SI] ;把【SI】的值给CX ADD BL,CL ;先加低八位 ADC BH,CH ;考虑进位
LEA DX,PR ;DX指向PR,换行 CALL OUTPUT
LEA DX,PR1 ;DX指向PR1,显示'A + B=' CALL OUTPUT
CALL OUTBX ;RET
JIA ENDP ;JIAN PROC NEAR ;IN16 ;SUB BX,[SI] ;NEG BX ;LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR2 ;DXCALL OUTPUT
CALL OUTBX ;RET
JIAN ENDP ;CHENG PROC NEAR ;IN16 ;MOV DX,0 ;MOV AX,BX ;MUL WORD PTR[SI] ;AXMOV BX,AX ;PUSH BX ;PUSH DX ;LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR3 ;DXCALL OUTPUT
POP DX ;MOV BX,DX ;CALL OUTBX ;POP BX ;CALL OUTBX ;RET
调用显示BX寄存器的内容函数 加法结束 减法函数
调用宏,接受键盘输入的两个十六进制数,第一个数由SI
指向,第二个数存放在BX中
第二个数减第一个数,结果存放到BX中
对结果取反后才是A-B的值,才是第一个数减去第二个数 指向PR,换行 指向PR2,显示'A - B=' 调用显示BX寄存器的内容 减法函数结束 乘法函数
调用宏,接受键盘输入的两个十六进制数,第一个数由SI
指向,第二个数存放在BX中
把DX清零
把第二个数赋给AX
乘[SI]并把结果存放到DX,AX中,是字的操作 将AX赋给BX
将BX压栈,显示下面DX的内容时要将DX的值赋给BX 将DX压栈,因为下面要换行输出,会改变DX的值 指向PR,换行输出 指向PR3,显示'A * B=' 将DX出栈,要将做乘法后DX的内容显示出来 把DX给BX 显示DX的内容 将BX出栈
显示AX的内容
CHENG ENDP ;乘法函数结束 CHU PROC NEAR ;除法函数
IN16 ;调用宏,接受键盘输入的两个十六进制数,第一个数SI指
向,第二个数存放在BX中
MOV AX,[SI] ;将第一个数赋给AX MOV DX,0 ;将DX清零
DIV BX ;AX除BX,结果存放到DX,AX,DX存放余数,AX存放商 PUSH DX ;压栈DX PUSH AX ;压栈AX
LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR4 ;DXCALL OUTPUT
POP AX ;MOV BX,AX ;CALL OUTBX ;LEA DX,PR5 ;DXCALL OUTPUT
POP DX ;MOV BX,DX ;CALL OUTBX ;RET
CHU ENDP ;OUTBX PROC NEAR ;MOV CH,4 ;CHROTATE:MOV CL,4 ;CLROL BX,CL ;MOV AL,BL ;AND AL,0FH ;ADD AL,30H ;AL+30HCMP AL,3AH ;JL PRINTIT ;ADD AL,7H ;PRINTIT:MOV DL,AL ;MOV AH,2
INT 21H ;DEC CH ;CH-1JNZ ROTATE ;CH!=0RET ;CH=0OUTBX ENDP ;CODE ENDS END MAIN
指向PR,换行 指向PR4,显示'A / B=' 出栈AX
将AX赋给BX,将商给BX
显示AX寄存器的内容,即显示商 指向PR5,显示省略号 出栈DX
将DX赋给BX,即将余数赋给BX, 显示DX寄存器的内容,显示余数 除法函数结束
显示BX寄存器的内容函数 等于4 等于4
将BX循环左移4位 将BL赋给AL 将AL的高位置0
可将AL变为对应的ASCII的值 判断是否是0-9之间 是则跳转到PRINTIT 是A-F再加上7H 将AL赋给DL 显示AL
再赋给CH
则跳转到ROTATE 则结束
显示寄存器BX内容函数结束
本科生课程设计成绩评定表
指导教师签字:
年 月 日
微机原理及接口技术
课程设计
题目 学院 专业 班级 姓名 指导教师
加减乘除四则运算程序
自动化学院 电气工程及其自动化
电气1204 李铭昕 李道远
2014 年 12 月 30 日
课程设计任务书
学生姓名: 李铭昕 专业班级: 电气1204班 指导教师: 李道远 工作单位: 自动化学院
题 目: 加减乘除四则运算程序 初始条件:
从键盘接受16进制数四则运算表达式。能实现加、减、乘、除的计算。执行时,需在显示屏上显示计算表达式并给出计算结果。按Q退出程序。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
(1) 设计任务及要求分析 (2) 方案比较及认证说明 (3) 系统原理阐述 (4) 硬件设计课题需要说明:硬件原理,电路图,采用器件的功能
说明 (5) 软件设计课题需要说明:软件思想,流程图,源程序及程序注
释 (6) 调试记录及结果分析 (7) 总结 (8) 参考资料 (9) 附录:芯片资料或程序清单,软件演示屏幕拷贝图或硬件
目录
1.概述 ................................................................ 5 1.1 设计任务 ........................................................... 5
1.2 设计功能 ...................................................................................................5 1.3 开发环境 ...................................................................................................5 2.程序设计 ............................................................ 5
2.1程序模块 ...................................................................................................5 2.2 主要算法 ...................................................................................................6 2.2.1 运算类型选择算法 ............................................................................6 2.2.2 字符输入算法 ....................................................................................7 2.2.3 四则运算算法 ....................................................................................8 2.2.4 输出算法 ..............................................................................................8 2.3 程序流程图 ..............................................................................................9 3 程序调试 ............................................................ 10
3.1.1 操作步骤 ............................................................................................10 3.1.2程序调试 .............................................................................................10 4 小结 ................................................................ 12 参考文献 .............................................................. 13 附录 .................................................................. 14 附录源程序清单 ........................................................ 14
摘要
在汇编语言程序设计时常用到四则运算,而汇编语言是低级语言,用它来实现四则运算较为困难。本次设计利用Emu8086集成环境以及各种指令来实现输入十六进制的加减乘除运算,同时在屏幕上显示计算表达式,结果以十六进制输出。汇编语言虽然没有高级语言一样具有较高的可读性,但是由于汇编语言是一种机器语言,所以它的效率要比高级语言高得多。此次设计主要通过课程设计深入了解语言的特点是用符号代替了机器指令代码,而且助记符与指令代码一一对应,基本保留了机器语言的灵活性。使用汇编语言能面向机器并较好地发挥机器的特性,得到质量较高的程序。
关键词:四则运算;算法选择;数制转换
加减乘除四则运算程序
1.概述
1.1 设计任务
本次设计要求系统可实现从键盘接受十六进制数的四则运算表达式,可以实现加减乘除四则运算并在屏幕上显示计算结果,按Q退出程序。
1.2 设计功能
本程序输入的两个数字最大为FFFF,两个数分别给BX和[SI],以便运算。程序执行前,先选择运算类型,如果输入字符不属于运算类型的一种,则显示错误。选择好运算类型后,输入数字。程序中规定数字的输入只能是0至9、A至F或a至f之间,超出此范围显示错误,重新输入。按Q选择退出程序,并按Y确认退出。
1.3 开发环境
Emu8086
2.程序设计
2.1程序模块
本程序分为三大模块,如图2-1所示。主要包括:
1.界面设置。主要实现确定界面样式的功能,并且提示该如何操作,以菜单形式显示。
2.选择算法设置。用+、-、*、/分别表示加、减、乘、除四种运算,通过输入符号来选择运算类型。
3.十六进制转换设置。无论是输入还是输出,都是以十六进制数表示的。而调用DOS输入或输出的则是字符的ASCII码值,所以数据输入输出是必有一个数据类型转换的过程。输入时,将输入字符的ASCII码转换成相应的十六进制数,并以此参与运算,输出时,以四位二进制数为一个单位转换成十六进制数相对应的ASCII码调用DOS输出即可得十六进制数的计算结果。
2.2 主要算法
2.2.1 运算类型选择算法
通过DOS调用输入运算加减乘除的符号,再用CMP指令使输入的运算符号与‘+’、‘-’、‘*’、‘/’依次比较,看输入的字符与那种运算符号相等从而确定运算的类型并提示输入数据。如果输入的字符不属于上述的四种符号会显示输入错误并提示重新输入。输入正确和错误的情况分别入图3-1和图3-2所示。
图2-1 程序模块
图3-1 运算符号输入正确时程序运行情况
图3-2 运算符号输入错误时程序运行情况
2.2.2 字符输入算法
调用DOS输入字符时,首先判断输入的字符是否为回车键,是回车键则退出。然后用CMP指令判断AL中的字符是否小于‘0’,小于则显示输入数据错误并提示重新输入数据。如果AL中的数字大于等于‘0’,在判断其是否小于等于‘9’,是的话,将AL中的数减去30H,得到相应的十六进制数。如果大于‘9’,则判断AL中的数是否小于‘A’,是的话则显示输入错误,提示重新输入数据。如果大于等于‘A’则判断其是否小于等于‘F’,是的话将AL中的数减去37H,得到相对应的十六进制数。如果大于‘F’,则和‘a’比较,如果小于‘a’则显示输入错误,并提示重新输入数据,如果大于等于‘a’,则和‘f’比较,如果小于等于‘f’则将AL中的数先减去20H再减去37H,得到其对应的十六进制数。输完数据后,程序跳转到数据保存的程序段中。
输入的数据放置于BX中,由于四位二进制数代表一位十六进制数,所以存入数据时,先将BX中的数据左移四位,然后将BX与AL相加所得结果放在BX中,这样可以保证输入的高位在BX的高位,输入的低位在BX的低位。保存完数据后程序会自动跳回数据输入程序。数据输入正确或错误时的程序执行情况如图3-3和图3-4所示。
图3-3 数据输入正确时程序运行情况
图3-4 数据输入错误时程序运行情况
2.2.3 四则运算算法
(1)加法。先输入第一个小于4位的十六进制数存入SI中并将SI中的数给DX,再输入第二个小于4位的十六进制数存入BX中。执行加法时,先用ADD指令将DL和BL中的数相加,所得的和放在BL中,然后用ADC指令执行DX和BX高八位的相加,这样可以考虑低八位产生的进位。
(2)减法:先输入第一个小于4位的十六进制数存入SI中,再输入第二个小于4位的十六进制数存入BX中,然后BX和[SI]中的内容相减存入BX中,再用NEG求反,即为第一个数减去第二个数的差,当结果为负数的时候,其值为补码。 (3)乘法:先输入第一个小于4位的十六进制数存入SI中,再输入第二个数存入BX中,把BX的值给AX,然后让AX乘以[SI],所得的数可能为32位的二进制数,这时,若要显示结果则需要分别将DX、AX中的内容赋给BX,接着依次显示DX、AX的内容,即为积。
(4)除法:先输入第一个小于4位十六进制数存入SI中,再输入第二个数存入BX中,将[SI]赋给AX作被除数,并且应该将DX清零以满足除法指令32位除以16位的要求,再让BX作除数,得到的商存放在AX中,余数放在DX中,然后依次赋给BX,将其依次显示即为商。
2.2.4 输出算法
字符输出同样是调用DOS功能。由于输出的运算结果确定是正确的十六进制数值,所以输出时不必像输入时那样去检测字符是否错误,只需将要输出的十六进制数码转换成相应的ASCII码值并注意输出顺序正确即可。具体的操作步骤如下:首先用ROL指令将BX中最高四位移到BL中,再将BL的数给DL,用AND指令将DL高四位清零,然后将DL中的数加30H,再判断此时的数是否大于39H,若不大于,说明该十六进制数在0至9之间,调用DOS输出即可。若DL中的数大于39H,则说明该十六进制数在A至F之间,这个时候,再给DL中的数加7H然后输出即可。由于BX有十六位二进制数,所以执行以上步骤四次就可以输出运算结果,执行次数通过CH控制,首先给CH赋值为4,没执行一次CH的数减一直至CH等于0。
2.3 程序流程图
图3-5 程序流程图
流程图如上所示,选择运算符时和‘+’、‘-’、‘*’、‘/’依此比较,相符则进行相应的运算,不符合则看输入是否为Q,不是的话则说明输入错误,提示出错,是Q则在此通过Y/N选择,Y为确定退出,N则返回重新输入。
3 程序调试
3.1.1 操作步骤
操作步骤如下:
1.按提示选择运算类别: +:加法 -:减法 *:乘法 /:除法
2.按提示输入一个不高于四位的十六进制数 3.再输入一个不高于四位的十六进制数 4.显示计算结果 5.按Q选择Y/N
3.1.2程序调试
加法:算法选择‘+’,按提示输入两个十六进制数,回车后显示计算式 和结果。程序运行截图如图3-1所示。
图3-1 加法程序截图
减法:算法选择‘-’,按提示输入两个十六进制数,回车后显示计算式和 结果,若结果为负数,则屏幕上结果显示为补码。程序运行截图如图3-2所示。结果为负数的程序运行截图如图3-3所示。
图3-2 结果为正数的减法
图3-3 结果为负数的减法
乘法:算法选择‘*’,按提示输入两个十六进制数,回车后显示计算式和结果。程序运行截图如图3-4所示。
图3-4 乘法程序截图
除法:算法选择‘/’,按提示出入两个十六进制数,回车后显示计算式和结果,结果包括商和余数。程序截图如图3-5所示。
图3-5 除法程序截图
退出程序:按Q,选择Y即可退出程序。程序截图如图3-6所示。
图3-6 退出程序部分截图
4 小结
本次十六进制四则运算的程序设计,对于我来说还是有一定难度的,因为用汇编语言来实现四则运算并没有高级语言来得简单,所以在写程序的时候也遇到了一些困难,特别是输入输出数据的时候要用程序实现数据转移到BX的时候,很容易搞混顺序,造成结果错误。但是经过一系列的调试后,这些问题都解决了。在调试的过程中也加深了我对8086指令系统的认识。本次的程序总的来说还是比较好的满足了设计的要求,但也有不足,比如,当输入超过了四位没有提醒以及结果溢出也无警示,这些都是有待改进的地方
参考文献
[1]刘其明.《汇编语言程序设计教程》.徐州:中国矿业大学出版社,2010.11 [2]竺士蒙、李可.《汇编语言程序设计》.北京:清华大学出版社.2006 [3]谢宋和、甘勇.《单片机模糊控制系统设计与应用实例[M]》.北京:电子工业出版社,1999
[4]王爽.《汇编语言》.北京:清华大学出版社.2003
[5]齐志儒、高福祥.《汇编语言程序设计[M]》.北京:北京大学出版社.2007 [6]沈美明、温冬婵编著《IBM—PC汇编语言程序设计(第二版)》.北京:清华大学出版社.2005
[7]彭虎、周佩玲、傅忠谦.《微机原理与接口技术(第三版)》.电子工业出版社.2011
附录
附录源程序清单
IN16 MACRO ;完成从键盘接受二个数并转换为十六制数,第一个数由
SI指向,第二个数存放在BX中
LEA DX,PR ;DX指向PR换行 CALL OUTPUT ;
LEA DX,INPUT1 ;DX指向INPUT1,提示输入第一个数 CALL OUTPUT
CALL INPUT ;把输入的数存放在BX中 LEA SI,RESULT ;SI指向RESULT
MOV [SI],BX ;把第一个十六制数存入RESULT的第一个位置 LEA DX,PR ;DX指向PR,换行 CALL OUTPUT
LEA DX,INPUT2 ;DX指向INPUT2,提示输入第一个数 CALL OUTPUT
CALL INPUT ;把输入的数存放在BX中 ENDM ;宏结束 DATA SEGMENT ;数据段 BUF DB ' ',0DH,0AH
DB '*------- WELCOME TO CALCULATOR SYSTEM ---------*',0DH,0AH
DB'*---‘+’:ADD--‘-’:SUB--‘*’:MUL--‘/’:DIV--Q:QUIT---------*'
,0DH,0AH
DB '*---------- 2014*12*31---------------*',0DH,0AH DB '*----------- Made by LMX--------*',0DH,0AH DB 0DH,0AH,'Please input the choose number:','$'
INPUT1 DB 'Please input the first number xiao yu 4 wei:','$' INPUT2 DB 'Please input the second number xiao yu 4 wei:','$' RESULT DW ?,? ;存放键盘输入的两个十六制数
WRO DB 'You input the number is wrong,please input again:',0DH,0AH,'$'; PR DB 0DH,0AH,'$' ;将光标移到下一行起始位置 PR1 DB 'A + B=$' PR2 DB 'A - B=$' PR3 DB 'A * B=$' PR4 DB 'A / B=$' PR5 DB '......$'
PR6 DB 'Are you sure exit?(Y/N)$' DATA ENDS ;数据段落定义结束 CODE SEGMENT
MAIN PROC FAR ;主函数 ASSUME CS:CODE ,DS:DATA START:
MOV AX,DATA MOV DS,AX
LEA DX,BUF ;DX指向BUF换行
CALL OUTPUT ;调用显示字符串函数换行 SUB AX,AX ;AX清零
CALL CHOOSE ;调用选择函数 JMP START ;跳转到START RET MAIN ENDP
INPUT PROC NEAR ;定义INPUT函数,就是将从键盘输入的数按原十六进制数
MOV BX,0 ;BXNEWCHAR:
MOV AH,1
INT 21H ;CMP AL,0DH ;JE EXIT
CMP AL,'0' ;JB CALL WRONG
CMP AL,'9' ;JBE H1 ;CMP AL,'A' ;JB CALL WRONG ;CMP AL,'F' ;JBE H0 ;CMP AL,'a' ;JB CALL WRONG ;CMP AL,'f' ;JBE H2 ;CALL WRONG ;H2:SUB AL,20H ;H0:SUB AL,37H ;JMP ADDTO ;H1:SUB AL,30H ;JMP ADDTO ;ADDTO:
MOV CL,4 ;SHL BX,CL ;MOV AH,0 ;ADD BX,AX ;AX+BX
JMP NEWCHAR ;EXIT: RET INPUT ENDP
OUTPUT PROC NEAR ;MOV AH,09H
存放在BX中
清零 接受键盘输入一个字符 输入与回车比较,是就结束 输入与0比较,小于则显示错误 大于0则和9比较
小于等于9则转换为对应的十六进制数 大于9则和A比较 小于A则显示错误 大于等于A则和F比较
小于等于F则将其转换为对应的十六进制数 大于F则和a比较 小于a则显示错误 大于a则和f比较
小于等于f则转换为对应的十六进制数 否则显示错误
若是a-f,则应该先减20H
由于41-A=37,完成把字母字符转换成对应的十六进制数 跳转到ADDTO
把0到9的字符转换成对应的十六进制数 跳转到ADDTO 相当于让BX乘以16 将BX逻辑左移 将AX清零 送到BX 跳转到NEWCHAR,把第二个输入的字符存放到BX的第二位 显示字符串函数
INT 21H RET
OUTPUT ENDP
CHOOSE PROC NEAR ;选择函数
MOV AH,1 ;从键盘接受一个数 INT 21H
CMP AL,'+' ;与+比较
JE YES1 ;等于+就跳转到YES1,进行加法 CMP AL,'-' ;与-比较
JE YES2 ;CMP AL,'*' ;JE YES3 ;CMP AL,'/' ;JE YES4 ;CMP AL,'Q' ;JE EXIT1 ;CALL WRONG ;EXIT1: LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR6 ;DXCALL OUTPUT
MOV AH,1 ;INT 21H
CMP AL,'Y' ;JE EXIT0 ;CMP AL,'y' ;JNE START ;EXIT0:MOV AH,4CH ;INT 21H
YES1:CALL JIA ;JMP START ;YES2:CALL JIAN ;JMP START ;YES3:CALL CHENG ;JMP START ;YES4:CALL CHU ;RET
CHOOSE ENDP ;WRONG PROC NEAR ;LEA DX,PR ;DXLEA DX,WRO ;DXJMP START ;RET
WRONG ENDP ;等于-就跳转到YES2,进行减法 与*比较
等于*就跳转到YES2,进行乘法 与/比较
等于/就跳转到YES2,进行除法 与Q比较
等于Q就跳转到EXIT1,结束程序 如果以上的数就提示出错 指向PR换行 指向PR6,确认是否退出 从键盘接受一个数 与Y比较
不是Y就看是否为y 与y比较
不是y就跳转到START 结束本程序 调用JIA函数
调用完之后跳转到START 调用JIAN函数
调用完之后跳转到START 调用CHENG函数
调用完之后跳转到START 调用CHU函数 选择函数结束 报错函数
指向PR换行
指向WRO,提示输入有错,请重新输入跳转到START 报错函数结束
JIA PROC NEAR ;加法函数
IN16 ;调用宏,接受键盘输入的两个十六进制数,第一个数由SI
指向,第二个数存放在BX中
MOV CX,[SI] ;把【SI】的值给CX ADD BL,CL ;先加低八位 ADC BH,CH ;考虑进位
LEA DX,PR ;DX指向PR,换行 CALL OUTPUT
LEA DX,PR1 ;DX指向PR1,显示'A + B=' CALL OUTPUT
CALL OUTBX ;RET
JIA ENDP ;JIAN PROC NEAR ;IN16 ;SUB BX,[SI] ;NEG BX ;LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR2 ;DXCALL OUTPUT
CALL OUTBX ;RET
JIAN ENDP ;CHENG PROC NEAR ;IN16 ;MOV DX,0 ;MOV AX,BX ;MUL WORD PTR[SI] ;AXMOV BX,AX ;PUSH BX ;PUSH DX ;LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR3 ;DXCALL OUTPUT
POP DX ;MOV BX,DX ;CALL OUTBX ;POP BX ;CALL OUTBX ;RET
调用显示BX寄存器的内容函数 加法结束 减法函数
调用宏,接受键盘输入的两个十六进制数,第一个数由SI
指向,第二个数存放在BX中
第二个数减第一个数,结果存放到BX中
对结果取反后才是A-B的值,才是第一个数减去第二个数 指向PR,换行 指向PR2,显示'A - B=' 调用显示BX寄存器的内容 减法函数结束 乘法函数
调用宏,接受键盘输入的两个十六进制数,第一个数由SI
指向,第二个数存放在BX中
把DX清零
把第二个数赋给AX
乘[SI]并把结果存放到DX,AX中,是字的操作 将AX赋给BX
将BX压栈,显示下面DX的内容时要将DX的值赋给BX 将DX压栈,因为下面要换行输出,会改变DX的值 指向PR,换行输出 指向PR3,显示'A * B=' 将DX出栈,要将做乘法后DX的内容显示出来 把DX给BX 显示DX的内容 将BX出栈
显示AX的内容
CHENG ENDP ;乘法函数结束 CHU PROC NEAR ;除法函数
IN16 ;调用宏,接受键盘输入的两个十六进制数,第一个数SI指
向,第二个数存放在BX中
MOV AX,[SI] ;将第一个数赋给AX MOV DX,0 ;将DX清零
DIV BX ;AX除BX,结果存放到DX,AX,DX存放余数,AX存放商 PUSH DX ;压栈DX PUSH AX ;压栈AX
LEA DX,PR ;DXCALL OUTPUT
LEA DX,PR4 ;DXCALL OUTPUT
POP AX ;MOV BX,AX ;CALL OUTBX ;LEA DX,PR5 ;DXCALL OUTPUT
POP DX ;MOV BX,DX ;CALL OUTBX ;RET
CHU ENDP ;OUTBX PROC NEAR ;MOV CH,4 ;CHROTATE:MOV CL,4 ;CLROL BX,CL ;MOV AL,BL ;AND AL,0FH ;ADD AL,30H ;AL+30HCMP AL,3AH ;JL PRINTIT ;ADD AL,7H ;PRINTIT:MOV DL,AL ;MOV AH,2
INT 21H ;DEC CH ;CH-1JNZ ROTATE ;CH!=0RET ;CH=0OUTBX ENDP ;CODE ENDS END MAIN
指向PR,换行 指向PR4,显示'A / B=' 出栈AX
将AX赋给BX,将商给BX
显示AX寄存器的内容,即显示商 指向PR5,显示省略号 出栈DX
将DX赋给BX,即将余数赋给BX, 显示DX寄存器的内容,显示余数 除法函数结束
显示BX寄存器的内容函数 等于4 等于4
将BX循环左移4位 将BL赋给AL 将AL的高位置0
可将AL变为对应的ASCII的值 判断是否是0-9之间 是则跳转到PRINTIT 是A-F再加上7H 将AL赋给DL 显示AL
再赋给CH
则跳转到ROTATE 则结束
显示寄存器BX内容函数结束
本科生课程设计成绩评定表
指导教师签字:
年 月 日