80X86汇编语言课程设计报告-打印水仙花数(含代码)

课程设计任务书

学生姓名:           专业班级:             

指导教师:           工作单位:             

题目: 打印水仙花数

初始条件:

理论:完成了《汇编语言程序设计》课程,对80X86系列编程结构和指令系统有了较深入的理解,已掌握了汇编语言程序设计的基本方法和技巧。

实践:完成了《汇编语言程序设计》的基本实验,熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法

要求完成的主要任务:

进一步理解和掌握较复杂程序的设计方法,掌握子程序结构、宏指令的设计和友好用户界面的设计。具体的设计任务及要求:

1) 键盘输入一个大整数n;

2) 将小于n的水仙花数打印出来(各位数字的立方和等于该数本身);

3) 程序采用子程序结构或宏指令,结构清晰;

4) 友好清晰的用户界面,能识别输入错误并控制错误的修改。

在完成设计任务后,按要求撰写课程设计说明书;对课程设计说明书的具体要求请见课程设计指导书。

阅读资料:

1)《80X86汇编语言程序设计(王元珍等)》例5.12

2)《汇编语言(王爽第3版)》实验1、实验2、实验3

时间安排:

设计安排二周:第18周:完成系统分析及设计,初步代码编写。

第19周:完成程序调试,撰写课程设计报告。

 

 

指导教师签名:                   2018年    月      日


打印水仙花数

1.需求说明

 1.1设计要求:

进一步理解和掌握较复杂程序的设计方法,掌握子程序结构的设计和友好用户界面的设计。

具体的设计任务及要求:

1.输入一个三位整数n;

2.将小于n的水仙花数打印出来(各位数字的立方和等于该数本身);

3.程序采用子程序结构或宏指令,结构清晰;

4.友好清晰的用户界面,能识别输入错误并控制错误的修改。

 1.2设计说明

     所谓“水仙花数”是指一个3位数,其个、十、百位数字的立方和等于其本身。

 1.3功能简述

    程序可以输入一个三位数,若输入有误则提示错误,并提示重新输入,若输入正确,系统将显示出所有大于等于100,并且小于等于输入数字的水仙花数。

然后提示是否继续,若用户输入y或Y,则系统回到最开始的状态,若输入n或N,则退出系统,若为其他则提示错误,并重新输入。

 

2.设计说明(简要的分析与概要设计)

 2.1简要分析

   2.1.1原理说明

(1)输入阶段:在数据段设置一个输入缓冲区,用于接收输入的字符串,判断输入的数是否为三位数,个位十位百位是否符合要求。若不符合,显示输入错误的信息。

(2)转化阶段:若输入的数符合要求,则将每一个字符转化为十六进制,并求出该数的真正数值,以十六进制形式保存。

(3)判断、输出水仙花数阶段:从(cx)=100开始循环,求(cx)的个位十位百位,并求其立方和,看看是否和(cx)自身相等。若相等,则(cx)为水仙花数,将其输出。若不相等,则(cx)+1,继续循环判断。当(cx)=输入数时循环结束,此时打印出了大于等于100,小于等于输入数的所有水仙花数。功能完成。

(4)询问阶段:询问用户是否重新执行该过程。是则重复以上阶段,否则退出程序。

   2.1.2程序流程图

(画出程序实现基本流程图,可以在学校网站下载Visio2016用其中的流程图功能绘制)

2.2 数据段设计

data segment
messsage1 db 0dh,0ah,'Please input a number(100<=number<=999):','$';输入一个三位数
messsage2 db 0dh,0ah,'Do you want to continue(y/n)?','$';是否继续
messsage3 db 0dh,0ah,'shuixianhuashu:',0ah,'$';打印水仙花数
error db 0dh,0ah,'Input error,please input again!','$';输入异常
charNum db 10;存放输入的数(字符串),最多可以输入9个数
          db 0
		  db 10 dup(0);最后一个人字符留给回车
realNum dw ?;存放由字符转换来的数
cxNum db 3 dup(?);存放100~输入数字间的每个数
data ends

3.主要子程序(或宏指令)设计与描述

(程序中一些常用模块如键盘输入、显示输出、数制转换(十进制转二进制、十六进制)、程序退出等用子程序或宏指令实现,使主程序代码看着简洁)

(1)子程序:input。

功能:输入一个三位数。

说明:在数据段定义了输入缓冲区charNum,输入三位数的百、十、个位字符分别存放于charNum[2]、 charNum[3] 、charNum[4]中。(charNum[0]存放缓冲区的最大容量,charNum[1]存放实际输入的字符数)   

(2)子程序:convert。

功能:将输入的字符转化为十六进制数,并处理错误输入。

说明:通过比较输入字符的ASCII码来判断个位、十位是否为0-9,百位是否为1-9,若不是,处理错误,重新调用子程序input。由于输入的三位数是字符形式,所以要将其每位数由ASCII码转化为16进制数(sub al,30h)。最后由个、十、百位求出真实的三位数值,存入realNum中。

(3)子程序:judge。

功能:判断并显示水仙花数。

说明:将cx置为100,将其作为计数器 ,循环赋值为100到输入数间的每一个三位数。(cx)/10的余数是个位(存入cxNum[2]),再将商/10得到的余数是十位(存入cxNum[1]),商是百位(存入cxNum[0])。用bx存放三位数的立方和,并与(cx)比较,若相等,则将cxNum中的数转换为字符后打印。此后(cx)+1,当(cx)=输入数时循环结束。

 

4.源程序与执行结果

4.1源程序代码

data segment
inputMess db 0dh,0ah,'Please input a number(100<=number<=999):','$';输入一个三位数
repeatMess db 0dh,0ah,'Do you want to continue(y/n)?','$';是否继续
printMess db 0dh,0ah,'shuixianhuashu:',0ah,'$';打印水仙花数
errorMess db 0dh,0ah,'Input error,please input again!','$';输入异常
charNum db 10;存放输入的数(字符串),最多可以输入9个数
        db 0
		db 10 dup(0);最后一个人字符留给回车
realNum dw ?;存放由字符转换来的数
cxNum db 3 dup(?);存放100~输入数字间的每个数
data ends

code segment
assume ds:data,cs:code
;************************************************************************************
;主程序:main
;功能:控制程序主流程
main proc far
start:
    mov ax,data
    mov ds,ax
go:;输入三位数,判断并显示水仙花数
    call input
    call judge
again:;询问是否继续
    lea dx,repeatMess
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    cmp al,89;Y的ASCII码
    je go	
	cmp al,121;y的ASCII码
	je go
	cmp al,78;N的ASCII码
	je exit
	cmp al,110;n的ASCII码
	je exit
	lea dx,errorMess
	mov ah,9
	int 21h
	jmp again
exit:
    mov ah,4ch
	int 21h
main endp
;************************************************************************************
;子程序:input
;功能:输入一个三位数
input proc near
    lea dx,inputMess
	mov ah,9
	int 21h
	mov ah,0ah
	lea dx,charNum;从键盘输入字符串
	int 21h
	call convert
	ret
input endp
;************************************************************************************
;子程序:convert
;功能:将输入的字符转化为十六进制数,并处理错误输入
;寄存器分配:
;al:存放每一位数
;bx:存放转换完毕的三位数
convert proc near
        xor bx,bx
		xor dx,dx
		xor ax,ax
		cmp charNum+1,3;判断输入的是否为三位数
		jne err
		
		mov al,charNum[4];判断个位是否为0~9
		cmp al,47;0的ASCII码是48
		jbe err
		cmp al,58;9的ASCII码是57
		jge err
		sub al,30h;将字符转化为数
		mov bx,ax
		
		mov al,charNum[3];判断十位是否为0~9
		cmp al,47
		jbe err
		cmp al,58
		jge err
		sub al,30h
		mov dh,10
		mul dh;10*(al)->ax
		add bx,ax;
		
		mov al,charNum[2];判断百位是否为1~9
		cmp al,48
		jbe err
		cmp al,58
		jge err
		sub al,30h
		mov dh,100;100*(al)->ax
		mul dh
		add bx,ax
		
		mov realNum,bx;将转化后的数存入realNum
		jmp return
		
	err:;处理错误输入
	    lea dx,errorMess
		mov ah,9
		int 21h
		call input
	return:
	    ret
	convert endp
;************************************************************************************
;子程序:judge
;功能:判断并显示水仙花数
;寄存器分配:
;ax:存放每一位数的平方
;bx:存放三位数立方之和
;cx:计数器,存放从100到输入三位数间的所有三位数
judge proc near
        lea dx,printMess
		mov ah,9
		int 21h
		
		mov cx,100
    digit_cube:
	    ;将百位的立方存入bx
	    mov ax,cx
		mov dh,100
		div dh;(al)=百位数
		mov cxNum[0],al;百位存入cxNum[0]
		mov dh,al;以下三行求百位数的立方,结果在ax中
		mul dh
		mul dh
		mov bx,ax
		
		;将十位的立方加入bx
		mov ax,cx
		mov dh,10
		div dh;(ah)=余数(个位),(al)=商(百位十位)
		mov ah,0
		div dh;商/10,(ah)=余数(十位),(al)=商(百位)
		mov cxNum[1],ah;十位存入cxNum[1]
		mov al,ah
		mov dh,ah
		mul dh
		mul dh
		add bx,ax
		
		;将个位的立方加入bx
		mov ax,cx
		mov dh,10
		div dh;(ah)=余数(个位)
		mov cxNum[2],ah;个位存入cxNum[2]
		mov al,ah
		mov dh,ah
		mul dh
		mul dh
		add bx,ax
		
		mov dx,cx
		cmp dx,bx;将当前数(cx)与位数平方之和(bx)比较
		je print;相等则是水仙花数,打印
		mov ax,realNum
		cmp cx,ax;将当前数(cx)与输入的数(ax)比较
		je stop;相等则终止
		inc cx;否则将当前数(cx)+1继续下轮比较
		jmp digit_cube
	
	print:
	    ;打印百位
		mov dl,cxNum[0]
		add dl,30h
		mov ah,2
		int 21h
		
		;打印十位
		mov dl,cxNum[1]
		add dl,30h
		mov ah,2
		int 21h
		
		;打印个位
		mov dl,cxNum[2]
		add dl,30h
		mov ah,2
		int 21h
		mov dl,20h
		int 21h
		
		mov ax,realNum
		cmp ax,cx
		je stop
		inc cx
		jmp digit_cube
		
	stop:
	    ret
	judge endp
;************************************************************************************
code ends
 end start

4.2 测试

 4.2.1 测试用例

  输入数字:

① 错误输入:99

② 错误输入:066

③ 错误输入:2333

④ 正确输入:345

⑤ 正确输入:999

    是否继续:

① 错误输入:1

② 错误输入:t

③ 正确输入:y

④ 正确输入:n

4.2.2 测试结果

5.总结

在这次汇编课程设计中,我更加深入地理解了相关的汇编知识,对于相关汇编指令的运用更加熟悉。我在这个过程中体会到了用汇编语言编程的不易,数据在寄存器、内存单元中的存储、转移真的是一件需要非常小心处理的事,每一步的结果都需要仔细计算求证,否则极易出错。

此外,我还深刻体会到绘制流程图对于程序设计的重要性,只有在写代码之前清楚、完备地考虑程序流程,才能做到事半功倍。依照程序流程图,一点一点地分析、实现程序模块,代码的编写就变得容易起来,相关错误的查找也会变得更加轻松。

 

6.参考资料

《80X86汇编语言程序设计》王元珍等 著

《汇编语言(第三版)》 王爽 著



  • 15
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值