实验目的
在对80x86系列编程结构和指令系统有了较深入的理解、已掌握了汇编语言程序设计的基本方法和技巧、熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法的基础上,进一步理解和掌握较复杂程序的设计方法,掌握子程序结构、宏指令的设计和友好用户界面的设计。
实验任务
采用DOSBox模拟Intel 8086(16位)处理器,使用汇编语言编写16位程序,完成以下实验程序设计任务及要求:
- 使用键盘输入一个整数n(100≤n≤999);
- 将小于等于n的水仙花数打印出来;
水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number)。水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身。
- 程序采用子程序结构或宏指令,结构清晰;
- 友好清晰的用户界面,能识别输入错误并控制错误的修改。
程序设计说明与描述
功能简述
启动程序,用户可以输入一个三位数,若输入有误则提示错误,并提示重新输入;若输入正确,系统将显示出所有大于等于100,并且小于等于该输入数字的水仙花数。
此后,程序提示是否继续。若用户输入’y’或’Y’,则系统回到最开始的状态;若输入’n’或’N’,则退出系统;若输入其他则提示错误,并提示重新输入。
程序流程图
数据段设计
设计了BUFFER_TRANSFORM、OUTPUT1~ OUTPUT7、BUFFER数据段、RESULT共计11个数据段。这些数据段存储的数据的含义如下:
- BUFF_TRANSFORM:存储数字的每一位的ASCII码(存储数字转换成的字符串)。在判断是否是水仙花数时,用于临时存储该数字的每一位数字的ASCII码;在输出水仙花数时,用于临时存储该数字的每一位数字的ASCII码。
- OUTPUT1:存储输入数字的提示。
- OUTPUT2:存储输入错误的提示。
- OUTPUT3:存储是否继续的提示。
- OUTPUT4:存储输出水仙花数(Narcissistic Number)的提示。
- OUTPUT5:存储未找到水仙花数的提示。
- OUTPUT6:存储程序结束的提示。
- OUTPUT7:存储空格。
- OUTPUT8:存储回车换行符。
- BUFFER:设置输入字符串长度为4,存储输入的字符串长度,存储输入信息。
- RESULT:存储计算结果。
DATA SEGMENT
;存储数字的每一位的ASCII码(存储数字转换成的字符串)
BUFFER_TRANSFORM DB 0,0,0,'$'
OUTPUT1 DB "Please input a number (100<=number<=999):",'$' ;存储输入数字的提示
OUTPUT2 DB "Input error , please input again ! ",0AH,0DH,'$' ;存储输入错误的提示
OUTPUT3 DB "Do you want to continue (y/n) ? ",'$' ;存储是否继续的提示
OUTPUT4 DB "Narcissistic Number: ",'$' ;存储输出水仙花数(Narcissistic Number)的提示
OUTPUT5 DB "Not Found!",'$' ;存储未找到水仙花数的提示
OUTPUT6 DB "Press any key to continue ! ",0AH,0DH,'$' ;存储程序结束的提示
OUTPUT7 DB ' ','$' ;存储空格
OUTPUT8 DB 0AH,0DH,'$' ;存储回车换行符
BUFFER DB 4,0,4 DUP (0) ;设置输入字符串长度为4,存储输入的字符串长度,存储输入信息
RESULT DW 4 DUP (0) ;存储计算结果
DATA ENDS
子程序设计与描述
- 子程序名称:CHANGE_LINE
子程序功能:输出回车换行。
子程序参数:无。 - 子程序名称:OUTPUT_ERROR_INFO
子程序功能:输出错误提示。
子程序参数:无。 - 子程序名称:DTOC
子程序功能:将数字转化为十进制字符串。
子程序参数:获取AX每一位的值,转换成ASSCII码,存入BUFFER_TRANSFORM。 - 子程序名称:CHECK_Narcissistic_Number
子程序功能:判断数字是否为水仙花数。
子程序参数:判断AX是否为水仙花数。若该数是水仙花数,CX=0;若该数不是水仙花数,CX≠0。 - 子程序名称:WRITE
子程序功能:将水仙花数写入RESULT区。
子程序参数:将水仙花数AX写入RESULT区,DI加二。
源程序代码
ASSUME CS:CODE,DS:DATA,SS:STACK
DATA SEGMENT
;存储数字的每一位的ASCII码(存储数字转换成的字符串)
BUFFER_TRANSFORM DB 0,0,0,'$'
OUTPUT1 DB "Please input a number (100<=number<=999):",'$' ;存储输入数字的提示
OUTPUT2 DB "Input error , please input again ! ",0AH,0DH,'$' ;存储输入错误的提示
OUTPUT3 DB "Do you want to continue (y/n) ? ",'$' ;存储是否继续的提示
OUTPUT4 DB "Narcissistic Number: ",'$' ;存储输出水仙花数(Narcissistic Number)的提示
OUTPUT5 DB "Not Found!",'$' ;存储未找到水仙花数的提示
OUTPUT6 DB "Press any key to continue ! ",0AH,0DH,'$' ;存储程序结束的提示
OUTPUT7 DB ' ','$' ;存储空格
OUTPUT8 DB 0AH,0DH,'$' ;存储回车换行符
BUFFER DB 4,0,4 DUP (0) ;设置输入字符串长度为4,存储输入的字符串长度,存储输入信息
RESULT DW 4 DUP (0) ;存储计算结果
DATA ENDS
STACK SEGMENT
DW 8 DUP (0)
STACK ENDS
CODE SEGMENT
START:
MOV AX,DATA ;初始化
MOV DS,AX
MOV AX,STACK ;建栈
MOV SS,AX
MOV SP,16
MOV DI,0
MOV CX,4
CLEAR_RESULT: ;清除由上一个输入计算出来的水仙花数
MOV WORD PTR [RESULT+DI],0
ADD DI,2
LOOP CLEAR_RESULT
INPUT: ;输入数字
MOV AH,09H ;显示提示
MOV DX,OFFSET OUTPUT1
INT 21H
MOV AH,0AH ;获取输入的字符串
MOV DX,OFFSET BUFFER
INT 21H
CALL CHANGE_LINE
MOV AL,[BUFFER+1] ;检查字符串长度
MOV AH,0
CMP AX,3
JE CHECK_NUM ;若长度为3,检查每一个字符是否在范围内
INPUT_ERROR_1: ;输入错误
CALL OUTPUT_ERROR_INFO ;输出输入错误提示
JMP INPUT ;返回,重新输入
CHECK_NUM: ;检查输入的每一位字符的ASCII码是否符合要求(是否是符合要求的数字)
CMP BYTE PTR [BUFFER+2],'0' ;检查第一位字符
JBE INPUT_ERROR_1 ;小于等于'0',输入错误
CMP BYTE PTR [BUFFER+2],'9'
JA INPUT_ERROR_1 ;大于'9',输入错误
CMP BYTE PTR [BUFFER+3],'0' ;检查第二位字符
JB INPUT_ERROR_1 ;小于'0',输入错误
CMP BYTE PTR [BUFFER+3],'9'
JA INPUT_ERROR_1 ;大于'9',输入错误
CMP BYTE PTR [BUFFER+4],'0' ;检查第三位字符
JB INPUT_ERROR_1 ;小于'0',输入错误
CMP BYTE PTR [BUFFER+4],'9'
JA INPUT_ERROR_1 ;大于'9',输入错误
;将输入的数计算出来,放入DX
MOV AL,[BUFFER+2]
SUB AL,30H ;计算出百位上的数字
MOV BL,100
MUL BL ;乘以100
MOV DX,AX ;百位乘以100的结果存储到DX
MOV AL,[BUFFER+3]
SUB AL,30H ;计算出百位上的数字
MOV BL,10
MUL BL ;乘以10
ADD DX,AX ;DX加上十位乘以10的结果
MOV AL,[BUFFER+4] ;计算出百位上的数字
SUB AL,30H
MOV AH,0
ADD DX,AX ;DX加上个位,得到输入的数
MOV AX,DX ;将输入的数据存储到AX
MOV DI,0
LOOP_CHECK_Narcissistic_Number:
CALL CHECK_Narcissistic_Number ;检查AX是否为水仙花数
CMP CX,0
JNE NEXT ;若CX≠0,则该数不是水仙花数,检查AX-1是否为水仙花数
CALL WRITE ;若CX=0,则该数是水仙花数,记下该水仙花数
NEXT:
DEC AX ;AX自减
CMP AX,100 ;若AX>=100,继续循环
JAE LOOP_CHECK_Narcissistic_Number
MOV AH,09H ;输出水仙花数提示
MOV DX,OFFSET OUTPUT4
INT 21H
CMP WORD PTR [RESULT],0
JNE FOUND ;若第一个结果不等于0,则找到了水仙花数
MOV AH,09H ;输出未找到水仙花数的提示
MOV DX,OFFSET OUTPUT5
INT 21H
FOUND:
MOV CX,4
MOV DI,0 ;DI:输出寻址控制
SHOW_NUM: ;将记下水仙花数输出
MOV AX,[RESULT+DI]
ADD DI,2
CMP AX,0
JE END_SHOW_NUM ;若该数为0,结束输出
CALL DTOC ;将水仙花数的每一位变成ASCII码放入BUFFER_TRANSFORM
MOV AH,09H ;输出该水仙花数(ASCII码)
MOV DX,OFFSET BUFFER_TRANSFORM
INT 21H
MOV AH,09H ;输出空格
MOV DX,OFFSET OUTPUT7
INT 21H
LOOP SHOW_NUM ;循环输出
END_SHOW_NUM:
CALL CHANGE_LINE
AGAIN:
MOV AH,09H ;输出是否继续提示
MOV DX,OFFSET OUTPUT3
INT 21H
MOV AH,1 ;获取输入的字符
INT 21H
CALL CHANGE_LINE
CMP AL,'n'
JE END_PROGRAM ;输入'n',程序结束
CMP AL,'N'
JE END_PROGRAM ;输入'N',程序结束
CMP AL,'y'
JE BACK ;输入'y',程序继续
CMP AL,'Y' ;输入'y',程序继续
JNE INPUT_ERROR_2
BACK: ;返回程序开始部分,程序继续
JMP FAR PTR START ;跳转回(JMP FAR)程序开始部分
INPUT_ERROR_2: ;输入错误
CALL OUTPUT_ERROR_INFO ;输出输入错误提示
JMP AGAIN ;返回,重新输入
END_PROGRAM:
MOV AH,09H ;输出程序结束提示
MOV DX,OFFSET OUTPUT6
INT 21H
MOV AX,4C00H
INT 21H
;名称:CHANGE_LINE
;功能:输出回车换行
;参数:无
CHANGE_LINE:
MOV AH,09H
MOV DX,OFFSET OUTPUT8
INT 21H
RET
;名称:OUTPUT_ERROR_INFO
;功能:输出错误提示
;参数:无
OUTPUT_ERROR_INFO:
MOV AH,09H
MOV DX,OFFSET OUTPUT2
INT 21H
RET
;名称:DTOC
;功能:将数字转化为十进制字符串
;参数:获取AX每一位的值,转换成ASSCII码,存入BUFFER_TRANSFORM
DTOC:
MOV SI,2
MOV CX,3
MOV BL,10
GET_NUM: ;获取该数每一位的值,转换成ASSCII码,存入BUFFER_TRANSFORM
DIV BL
ADD AH,30H
MOV [BUFFER_TRANSFORM+SI],AH
MOV AH,0
DEC SI
LOOP GET_NUM
RET
;名称:CHECK_Narcissistic_Number
;功能:判断数字是否为水仙花数
;参数:判断AX是否为水仙花数
;返回:若该数是水仙花数,返回CX≠0;若该数不是水仙花数,返回CX=0
CHECK_Narcissistic_Number:
PUSH AX ;保护数据
CALL DTOC ;计算AX每一位的数字
MOV CX,3
MOV DX,0
MOV SI,0
ADD_NUM: ;计算每一位的立方和
MOV AL,[BUFFER_TRANSFORM+SI]
SUB AL,30H
MOV AH,0
MOV BL,AL
MUL BL
MUL BL
ADD DX,AX
INC SI
LOOP ADD_NUM
POP AX ;恢复数据
MOV CX,AX
SUB CX,DX ;原数与计算结果相减,若该数是水仙花数,CX=0;若该数不是水仙花数,CX≠0
RET
;名称:WRITE
;功能:将水仙花数写入RESULT区
;参数:将水仙花数AX写入RESULT区,DI加二
WRITE:
MOV [RESULT+DI],AX
ADD DI,2
RET
CODE ENDS
END START
文章推荐
参考文献
[1]王爽.汇编语言程序设计(第三版), 北京:清华大学出版社,2013.
[2]钱晓捷.汇编语言程序设计(第五版),北京:电子工业出版社,2018
[3]王元珍,曹忠升,韩宗芬.80x86汇编语言程序设计,湖北:华中科技大学出版社,2005