微机闰年判断程序设计Word格式.docx
《微机闰年判断程序设计Word格式.docx》由会员分享,可在线阅读,更多相关《微机闰年判断程序设计Word格式.docx(16页珍藏版)》请在冰点文库上搜索。
![微机闰年判断程序设计Word格式.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/96701f11-bce5-4d57-8dba-792c2eeb05ab/96701f11-bce5-4d57-8dba-792c2eeb05ab1.gif)
(4)硬件设计课题需要说明:
硬件原理,电路图,采用器件的功能说明
(5)软件设计课题需要说明:
软件思想,流程图,源程序及程序注释
(6)调试记录及结果分析
(7)总结
(8)参考资料
(9)附录:
芯片资料或程序清单,软件演示屏幕拷贝图或硬件实物图
目录
摘要1
1.设计任务及要求分析2
1.1课程设计的目的2
1.2闰年判断程序设计2
2.方案比较及认证说明3
2.1方案比较3
2.1.1采用汇编语言设计3
2.1.2采用C语言设计3
2.2方案论证3
3.系统原理阐述4
3.1软件思想4
3.2程序设计原理4
3.3程序设计流程图4
3.4汇编源程序5
3.4.1主模块程序5
3.4.2子模块程序设计5
4.调试记录及结果分析7
4.1运行界面记录7
4.2算法分析8
4.3调试过程及结果分析8
心得体会9
参考文献10
附录11
摘要
本次微机原理与接口技术课程设计是要设计一个判断年份是否为闰年的显示程序。
本次课程设计用的是8086最小系统,在emu8086汇编集成环境下完成。
首先,根据课设题目要求进行分析,并选择适合要求的方案,在选定方案下设计整个设计要求的程序框架,画出流程框图,然后运用模块化的设计思想,将题设要求分成几个小的模块,一段一段的设计程序。
再分段对程序进行编写和调试,在编写程序时,每个版块都使用了分支语句,并在主程序中多次使用,同时主程序中还多次使用分支语句。
最后,完成各个板块的的设计之后,在分别进行调试和最终调试,并进行错误修改,对整体进行完善。
关键词:
汇编语言;
闰年判断;
EMU8086
1.设计任务及要求分析
1.1课程设计的目的
(1)使学生能够较全面地巩固和应用课堂中所学的基本理论和程序设计方法,能够较熟练地完成汇编语言程序的设计和调试。
(2)培养学生从资料文献、科学实验中获得知识的能力,提高学生从别人经验中找到解决问题的新途径的悟性,初步培养工程意识和创新能力。
1.2闰年判断程序设计
该年不是闰年,如果输入的是非法字符,则显示错误,重新输入。
从上述要求分析,本次设计要使用多次循环语句和分支语句,循环语句用来将字符串转换成十六进制数字,表示年份,分支语句在进行计算后判断余数是否为零从而判断输入年份是否为闰年。
所以对本次设计使用模块化思想,用子程序完成字符转换功能,主程序完成闰年判断并显示功能。
2.方案比较及认证说明
2.1方案比较
程序要求实现通过键盘输入一年份,然后判断该年份是否为闰年,如果是闰年,则在屏幕上显示:
2.1.1采用汇编语言设计
方案一:
采用汇编语言,使用软件EMU8086设计。
将输入年份保存到AX中,然后判断(((AX)MOD4EQUO)AND((AX)MOD100EQU0))OR((AX)MOD400EQU0),通过分支语句,若满足上述条件则输出“该年为闰年”,否则输出“该年不为闰年”。
2.1.2采用C语言设计
方案二:
采用机器编程语言,使用软件C++设计。
将输入年份复制给X,然后通过语句((X%4==0?
)AND(X%100==0?
))OR(X%400==0?
)判断输入年份是否为闰年。
满足条件将输出“该年为闰年”,否则输出“该年不为闰年”。
2.2方案论证
方案一采用的是汇编语言,汇编语言直接描述机器指令,比机器指令容易记忆和理解,而且可以通过调试观察数据在内存中的存储状态,将软件与硬件相结合。
汇编语言是低级语言,在编写程序的时候会把根据不同的情况指定使用不同的寻址方式,能够对内存和CPU里的通用寄存器直接操纵。
不同的计算机系列会有不同的汇编语言而C语言是高级语言,可以实现跨平台。
编写程序无需指定CPU的指令执行情况,一段程序可以在不同体系结构的计算机上使用。
C语言的使用范围更为广阔,但在初学计算机语言时,使用汇编语言可以更容易理解软件与硬件之间的联系,了解算法执行的过程,故在本次设计中采用方案一进行设计,而且程序简单,可使用单步调试,逐步分析每一句程序的运行过程。
3.系统原理阐述
3.1软件思想
EMU8086是DigitalRiver公司推出的一款较为先进的16位PC仿真软件,他将汇编语言程序设计和虚拟接口技术有机的结合起来,它内部集成了汇编语言的源程序的编译器和连接器,并提供一些参考例程,带有学习指南,还提供诸如交通灯、异步电机等一系列虚拟外设,是学习Inter8086/8088微处理器的工作原理和进行汇编语言设计的较为理想的工具。
其操作界面简单直观,有菜单栏、快捷按钮。
通过他们可以方便观察到处理器执行指令的各个步骤,其中的单步调试(singlestep)功能能显示指令执行后CPU内部存储器、堆栈区、变亮和标志寄存器的当前值。
这个模拟器是在一台“虚拟”的电脑上运行程序的,他拥有自己独立的“硬件”,这样程序就如同诸如硬盘与内存这样的实际硬件完全隔离,动态调试非常方便。
8086机器代码同Inter下一代处理器完全兼容,这意味着8086代码具有非常广泛的运用范围,另一特点是他的指令集非常小,学起来方便,同主流汇编程序相较,其语法简单得多,但是他能生成任何兼容8086机器语言的代码。
3.2程序设计原理
总体程序设计原理是由汇编语言编写的判断年份是否为闰年的小程序。
在运行程序后,屏幕会先提示输入一个年份,操作者输入年份后系统会自动判断该年是否为闰年,判断的语句为:
((AX)MOD4EQUO)AND((AX)MOD100EQU0))OR((AX)MOD400EQU0)。
AX为累加器,其中存放的是操作者输入的年份。
程序完成的主要功能有:
1.提示操作者输入一个年份2.判断年份是否闰年3.输出该年份是否为闰年。
3.3程序设计流程图
闰年判断流程图见图3-1-1。
图3-3-1程序框图
3.4汇编源程序
3.4.1主模块程序
主模块:
显示提示输入年份以及输入的字符内容,和最后输出的判断是否为闰年。
3.4.2子模块程序设计
子模块:
①判断输入:
该模块是对输入的年份的格式的判断,若是错误则显示错误Error,正确则进行下面的操作。
②字符串转换格式:
将数字字符串转换成数字,以便进行下面的程序操作。
③判断闰年:
判断输入的年份是否为闰年,若是则输出“Thisisaleapyear!
”,若不是则输出“Thisisnotaleapyear!
”,然后退出。
ifyearsprocnear;
此子程序用来判断年份是否为闰年
pushbx
pushcx
pushdx
movax,w;
把转换后的年份的数值存入AX
movcx,ax
movdx,0;
将dx清零
movbx,4;
把4存放到寄存器bx中(除数)
divbx;
除法指令
cmpdx,0;
将dx中的余数与0进行比较,看似否整除
jnzlab1;
若不相等跳转
movax,cx;
判断年份是否位400的整数倍
movbx,100;
将100赋给bx寄存器,做div的源操作数
movdx,0
divbx
jnzlab2
movbx,400
cmpdx,0
jzlab2
lab1:
clc;
清除进位标志,即非闰年
jmplab3
lab2:
stc;
设置进位标志,即闰年
lab3:
popdx
popcx
popbx
ret;
子程序返回指令
ifyearsendp
4.调试记录及结果分析
4.1运行界面记录
当输入为一个闰年、非闰年、非法输入时,程序所有运行过程如下图4-1-1至图4-1-3。
图4-1-1输入闰年
图4-1-2输入非闰年
图4-1-3非法输入
4.2算法分析
本次设计中判断闰年的主要算法为((AX)MOD4EQUO)AND((AX)MOD100EQU0))OR((AX)MOD400EQU0),要使用分支语句进行设计,余数是否为零是产生分支的原因。
第二个算法是字符串转换其对应的十六进制数值,对每一位字符减去48即30H就可以转换成为16进制数。
4.3调试过程及结果分析
INT
21h
/
AH=0Ah
-
input
of
a
string
to
DS:
DX,
fist
byte
is
buffer
size,
second
number
chars
actually
read.
this
function
does
not
add
'
$'
in
the
end
string.to
print
using
AH=9
you
must
set
dollar
character
at
it
and
start
printing
from
address
DX
+
2.
进行程序调试时,对字符串的定义不清,所以在给变量进行定义时分配内存空间出错。
然后是对闰年计算出错,在进行闰年计算时,将字符串首位转换为年份的千位要连续三次乘以十,此时CX控制循环次数所以要对CX重新进行赋值,百位,十位的转换类似,都要对CX重新赋值。
第三个问题是在主模块设计时,要对标志寄存器初始化,由于在进行语句编写后,计数寄存器有了初值要进行后续编写时要清零,这是本次编写程序中存在的最细微但是影响最大的问题,直接导致程序的功能出错。
调试过程中出现错误如图4-3-1。
图4-3-1CX有初值未清零
心得体会
通过本次课程设计,了解了EMU8086系统的编程方法,学习了如何编写简单的汇编语言程序。
在编程的过程中,发现了很多的问题,对汇编语句的不熟悉是最大的问题。
比如分支语句,跳转语句,在比较时,标志寄存器发生变化与否是比较和是否跳转的关键。
除法语句在使用时不够16位或32位的要进行拓展
否则无法进行除法语句的操作,商和余数分别存放在AH和AL中,故在判断余数是否为零时要与AL相比较,而非AX.。
在同学的帮助下,通过查找资料和不断的调试最终解决问题。
这次课程设计锻炼了发现问题,解决问题的能力,同时也锻炼了查找资料,阅读文献的能力,为以后的毕业设计和论文写作打下基础。
微机原理与借口技术在自动化专业中要经常使用,故这门课的课程设计也提高运所学知识的能力,通过实践检验理论知识,加强对知识的掌握,最终运用到今后的科研或工作当中。
感谢在此次课程设计中给予帮助的老师和同学。
回顾此次课程设计,课程设计是一个把需求分析、程序编写、程序调试、撰写报告结合为一体的过程。
在这个过程中,不仅锻炼了缜密的思维和坚持不解的毅力,更需要互助的精神。
只有通过一起努力才能将课程设计的所有环节都顺利的完成。
另外程序设计中遇到问题并解决问题的过程,使得独自探索并解决问题的能力了有了一个提高,这有利于以后的学习。
同时这整一个过程,也对程序编写的整个过程有了一个统筹全局的思想,因为需求分析、程序编写、程序调试、撰写报告这些过程是环环相扣的,绝对不可能独立进行。
参考文献
[1]李艳芳EMU8086和DEBUG在微机教学中的运用湖南科技学院学报2013
[2]刑江基于EMU8086汇编语言设计探讨湖北师范学院学报2010
[3]古兆麟基于EMU8086虚拟微机系统实验设计天津职业师范技术学院学报2011
[4]宋长军汇编语言学习与编程规律浅谈吉昌学院学报2008
[5]熊小兵汇编语言程序设计的比较方法学计算机教育2010
[6]EMU8086在微机原理教学中的运用黑龙江科技信息2009
[7]彭虎微机原理与接口技术电子科技大学出版社
[8]RandallHyde.TheArtofAssemblyLanguage[M].NoStarch.2005
[9]KipR.Irvine.AssemblyLanguageforx86Processors(6thEdition)[M].PrenticeHall.2011
[10]Juola.PrinciplesofComputerOrganizationandAssemblyLanguage,UsingtheJavaVirtualMachine[M].Prentice-Hall.2007
附录
使用的元件清单:
A.带有EMU8086的计算机一台
源程序:
datasegment
infondb0dh,0ah,'
inputayear:
$'
Ydb0dh,0ah,'
Thisisaleapyear!
Ndb0dh,0ah,'
Thisisnotaleapyear!
Edb0dh,0ah,'
Error!
wdw0;
用于保存输入的年份的数值,因为输入的年份是字符串,因此需要转换为数
bufdb8
db'
?
db8dup('
);
定义输入缓冲区
dataends
stacksegmentstack
db200dup(0)
stackends
codesegment
assumeds:
data,ss:
stack,cs:
code
start:
movax,data
movds,ax
leadx,infon;
在屏幕上显示提示信息
movah,9;
显示字符串
int21h
leadx,buf;
从键盘输入年份字符串
movah,0Ah;
0AH功能调用从键盘接受字符串到内存的输入缓存区
int21h
xorcx,cx
movcl,buf+1;
把输入的字符的个数保存在cl中
leadi,buf+2;
把从键盘输入字符的首地址存放到di中
pushax
a0:
moval,[di]
cmpal,0dh
jza1
cmpal,'
9'
jga3
0'
jla3
incdi
jmpa0
a1:
popax
calldatacate;
调用datacate子程序
callifyears;
调用ifyears子程序
jca2;
如果进位则跳转
leadx,n;
输出不是闰年
movah,9
jmpexit
a2:
leadx,y;
输出是闰年
callexit
a3:
leadx,e
exit:
movah,0
int16h
movah,4ch;
返回操作系统
datacateprocnear;
用于把表示年份的字符串转换为数值
pushcx;
deccx;
让cx寄存器自减1
leasi,buf+2;
把字符串的首地址保存在源地址寄存器SI中让si指向字符串的最低位
p1:
incsi
loopp1
popcx
movdh,30h
movbl,10
movax,1
p2:
pushax
subbyteptr[si],dh;
ASCII码字符,减去30H后转换十六进制数
mulbyteptr[si];
计算ax乘以字符数字
addw,ax;
把计算结果累加,并保存在w中
popax;
出栈操作,去除上一次操作后的倍数
mulbl;
乘以bl,计算当前的倍数
decsi;
修改源地址寄存器si的值,使得si指向下一个字符(即高位)
loopp2;
循环直到所有字符处理完毕(
datacateendp
codeends
endstart