葛磊课程设计.docx
《葛磊课程设计.docx》由会员分享,可在线阅读,更多相关《葛磊课程设计.docx(18页珍藏版)》请在冰豆网上搜索。
![葛磊课程设计.docx](https://file1.bdocx.com/fileroot1/2023-1/23/8deda8e7-f67d-4faf-a769-463684734102/8deda8e7-f67d-4faf-a769-4636847341021.gif)
葛磊课程设计
郑州航空工业管理学院
微机原理与接口技术课程设计报告
题目用字符组成汽车图形在屏幕显示从左向右开动的汽车
姓名葛磊
学号110607111
同组成员郭振乾姬恩泽
指导教师王春彦
二О一三年12月12日
一.设计任务
要求:
利用汇编语言进行动态图形设计。
内容:
小车在公路上行驶,从屏幕左侧驶向右侧。
在到达屏幕右侧,公路下降一段距离并改变颜色,然后小车继续由左向右行驶驶。
当下降到屏幕底部时,又返回到屏幕顶部重复上述过程,直到有键按下。
公路和小车的颜色不样。
也要用INT10H功能。
二.程序流程图及设计思路
本程序主要分三段:
数据段,堆栈段及代码段。
其中数据段定义了小车的图形集,堆栈段定义了堆栈空间,代码段执行各种功能,大体包括显示图形,延时,移动图形,清屏等,
用三个循环实现动画整个功能:
一、让小车从屏幕左侧跑到右侧
二、让小车不断从屏幕上端跳到下端
三、不断重复这一屏。
定义了清屏、输出字符的宏,定义了显示小汽车和移动小汽车的子程序。
本次动态图形设计,调用CRT显示功能实现。
调用BOISint10h中断的相关功能,具体用以下步骤进行:
1.确定小车由哪些字符组成。
2.在设定的屏幕上显示小车图形。
3.延迟一个时间周期,使动态图形更清晰。
4.清除图形。
5.改变图形的行列坐标,修改图形显示位置,重复2、3、4步骤。
6.写一个循环子程序,让小车从屏幕左侧行驶到屏幕右侧。
7.用loop指令,改变行坐标,让小车从屏幕的上一端跳到屏幕的下一端,重复执行,显示一屏。
8.用loop指令,不断重复这一屏。
我的程序还有一个小技巧,清屏的时候不是像别人那样写长串代码,而是通过重新设置显示方式来清屏,这样程序变得简单。
数学和逻辑推理对程序设计的重要性,找到简单、合适高效的算法可以大大节约程序运行时间和空间,优化了程序,提高程序运行效率,对于一个优秀的程序员来说非常重要。
流程图如下:
三.程序设计及其调试
clearmacrosch,scl,sdh,sdl,sbh;清屏宏定义
movah,0;设置显示方式为640*350彩色图形方式
moval,10h
int10h
movah,6;调用6号功能设置整个屏幕为bh值所对应的属性
subal,al
moval,1;设置滚动行数为1
movch,sch;窗口左上角(0行,0列)
movcl,scl
movdh,sdh;窗口右下角(dh,79),行号dh每次加3
movdl,sdl
movbh,sbh;道路属性,bh每次加1
int10h
endm
show_strmacrotishi;输出字符宏定义
leadx,tishi
movah,09
int21h
endm
;-----------------------------------------------------------------
datasegment
tishi1db'Welcometorunthisprogram.',0dh,0ah,'$'
tishi2db13,10,'$'
tishi3db'Thisisproductedbyhoujie$'
tishi4db13,10,'$'
tishi5db'Now,input1or2torunthisprogram(function1:
showarunningcar,function2:
exit):
',0dh,0ah,'$'
cardb8;小汽车的字符组合图形字符
db0dch,0bh,0,0
db4dup(0dbh,15,0,1)
db0dch,0bh,0,0
db4fh,7,1,-1
db4fh,7,0,-2
char_cntdw?
pointerdw?
;指针存偏移地址
linedb?
;存行号
columndb?
;存列号
dataends
;---------------------------------------------------------------------
stacksegmentstack
db200dup(?
)
stackends;堆栈缓冲区
;----------------------------------------------------------------------
codesegment
assumecs:
code,ds:
data
start:
movax,data
movds,ax
movah,0;设置显示方式为640*350彩色图形方式
moval,10h
int10h
show_strtishi1;在显示器上显示字符串提示信息
show_strtishi2
show_strtishi3
show_strtishi4
show_strtishi5
movah,01h;输入1或者2
int21H
cmpal,31h;比较输入的字符是否为1
jnea;不是1则转移到a
callshowcar
subax,ax
a:
cmpal,32h;比较输入的字符是否为2
jnestart
b:
movah,4ch;终止当前程序并返回调用程序
int21h
;------------------------------------------------------------------------------
showcarprocnear;显示小汽车子程序
movah,0;设置显示方式为640*350彩色图形方式
moval,10h
int10h
pushdx
pushbx
cmpax,ax;zf标志位置1
subsi,si
movdh,3
movbh,7
next:
cmpdh,22;公路是否退至屏幕底端?
jbnext1
subdh,dh
movdh,3
next1:
movah,01h;检查键盘缓冲区中有无输入字符(zf是否等于0)
int16h
jnefh;zf等于0则退出程序
;实现下移公路并改变颜色
clear0,0,dh,79,bh;清屏宏调用
leadi,car;di指向字符图形表
pushdx
callcar_move
cmpsi,1
jefh
popdx
popax
adddh,3
addbh,1
cmpbh,8;循环改变公路的颜色
jbbs
subbh,bh
movbh,1
bs:
movah,01h;检查键盘缓冲区中有无输入字符(zf是否等于0)
int16h
jnefh;zf等于0则退出程序
jmpnext
fh:
ret
showcarendp
;------------------------------------------------------------------------------
car_moveprocnear;移动子程序
pushax
pushbx
pushcx
subdh,2;从第2行1列位置开始显示汽车
movdl,0
pushdx
pushdi
movah,0fh;取当前显示方式
int10h
subch,ch
movcl,[di];cl存放字符个数
incdi;di指向字符图形表中的第一个字符
movchar_cnt,cx;存值
movpointer,di
movline,dh
movcolumn,dl
locationnew_next:
movah,01h;检查键盘缓冲区中有无输入字符(zf是否等于0)
int16h
jneexit3;zf不等于0执行exit3,等于0则退出程序
adddh,[di+2];改变行列坐标
adddl,[di+3]
cmpdl,80;小车超过屏幕与否?
jbshow_string
popdi
popdx
popcx
popbx
popax
jmpexit2
show_string:
movah,2;重新置光标位置
int10h
moval,[di];取字符值,显示小车
movbl,[di+1];取字符属性,移动了小车
pushcx
movcx,1
movah,09;显示字符
int10h
popcx
adddi,4;di指向下一个字符
looplocationnew_next
calldelaytime
callerase;擦除,小车显示到下一位置
jmpshortlocationnew_next
exit2:
ret
exit3:
movsi,1
jmpexit2
car_moveendp
;------------------------------------------------------------------------------
eraseprocnear;擦除子程序
movcx,char_cnt
movdi,pointer
movdh,line
movdl,column
erase_next:
adddh,[di+2]
adddl,[di+3]
movah,2
int10h
moval,[di]
movbl,0
pushcx
movcx,1
movah,9
int10h
popcx
adddi,4
looperase_next
movcx,char_cnt
movdi,pointer
movdh,line
inccolumn
movdl,column
ret
eraseendp
;------------------------------------------------------------------------------
delaytimeprocnear;延时子程序
pushcx
pushdx
movdx,20000;最大到65530
dly1:
movcx,6801
dly2:
loopdly2
decdx
jnzdly1
popdx
popcx
ret
delaytimeendp
;------------------------------------------------------------------------------
codeends
endstart
(一)定义一个清屏宏clear,并且定义哑元sch,scl,sdh,sdl,sbh进行传参引用。
代码具体分析如下:
movah,0;设置显示方式为640*350彩色图形方式
moval,10h
int10h
movah,6;调用6号功能设置整个屏幕为bh值所对应的属性
subal,al
moval,1;设置滚动行数为1
movch,sch;窗口左上角(0行,0列)
movcl,scl
movdh,sdh;窗口右下角(dh,79),行号dh每次加3
movdl,sdl
movbh,sbh;道路属性,bh每次加1
int10h
sch和scl分别显示左上角的行和列,sdh和sdl分别显示右上角的行和列,sbh表示显示道路属性。
定义清屏宏方便以后的程序多次调用,可简化程序结构、增加源程序的可读性、提高源程序的可维护性。
此程序显示方式均设为640*350彩色图形方式
(二)定义输出字符宏show_str,哑元tishi进行传参,leadx,tishi,将tishi的有效地址放入dx里面再显示出来。
(三)界面提示输入,用call指令调用showcar子程序,主要代码如下:
movah,01h;输入1或者2
int21H
cmpal,31h;比较输入的字符是否为1
jnea
callshowcar
subax,ax
a:
cmpal,32h;比较输入的字符是否为2
jnestart
b:
movah,4ch;终止当前程序并返回调用程序
int21h
输入1或者2,cmp指令判断输入的是1的话,则调用子程序showcar,若不是则跳转到标号a进行cmp指令判断是否是2,若是2则推出程序,若不是则返回初始。
(四)显示小汽车子程序,定义showcar子程序,并且实现下移公路改变颜色。
1、movah,1;设置显示方式为640*350彩色图形方式
moval,10h
int10h
pushdx
pushbx
cmpax,ax;zf标志位置1
subsi,si
movdh,3
movbh,7
next:
cmpdh,22;公路是否退至屏幕底端?
jbnext1
subdh,dh
movdh,3
next1:
movah,01h;检查键盘缓冲区中有无输入字符(zf是否等于0)
int16h
jnefh;zf等于0则退出程序
将标志位置1,设置7行,每行间隔3,屏幕为22行,比较公路是否退至屏幕底端,若是则返回屏幕最上面,若不是则跳到标号next1,检查键盘缓冲区中有无输入字符(zf是否等于0),zf不等于0则显示小车,否则执行fh推出程序。
2、实现下移公路并改变颜色,调用清屏宏clear和call指令调用car_move子程序。
clear0,0,dh,79,bh;清屏宏调用
leadi,car;di指向字符图形表
pushdx
callcar_move
cmpsi,1
jefh
popdx
popax
adddh,3
addbh,1
cmpbh,8;循环改变公路的颜色
jbbs
subbh,bh
movbh,1
bs:
movah,01h;检查键盘缓冲区中有无输入字符(zf是否等于0)
int16h
jnefh;zf等于0则退出程序
jmpnext
实现公路颜色的改变,小车每次跳转一次就改变一次公路颜色。
比较si中的值是否是1,若等于就执行fh推出程序,不是1,就道路坐标增加3行,bh加1。
cmp指令循环改变公路颜色,bh小于8执行bs,否则bh清零。
(五)小车移动子程序car_move,让小车从屏幕左侧跑到右侧,让小车不断从屏幕上端跳到下端
调用了延时delaytime子程序和擦出子程序erase,此处可以通过改变di和小车初始位置实现小车从不同位置不同方向移动。
movah,0fh;取当前显示方式
int10h
subch,ch
movcl,[di];cl存放字符个数
incdi;di指向字符图形表中的第一个字符
movchar_cnt,cx;存值
movpointer,di
movline,dh
movcolumn,dl
locationnew_next:
movah,01h;检查键盘缓冲区中有无输入字符(zf是否等于0)
int16h
jneexit3;zf不等于0执行exit3,等于0则退出程序
adddh,[di+2];改变行列坐标
adddl,[di+3]
cmpdl,80;小车超过屏幕与否?
jbshow_string
popdi
popdx
popcx
popbx
popax
jmpexit2
show_string:
movah,2;重新置光标位置
int10h
moval,[di];取字符值,即小车
movbl,[di+1];取字符属性,移动了小车
pushcx
movcx,1
movah,09;显示字符
int10h
popcx
adddi,4;di指向下一个字符
looplocationnew_next
calldelaytime;调用延时子程序
callerase;调用擦除子程序,小车显示到下一位置
jmpshortlocationnew_next
exit2:
ret
exit3:
movsi,1
jmpexit2
car_moveendp
设置从第2行1列位置开始显示汽车,movah,ofh取当前显示方式,将ch清零,把di寄存器的值放入cl,之后di自加1,将cx,di,dh,dl分别放入寄存器保存。
再检查键盘缓冲区中有无输入字符(zf是否等于0),zf等于0则退出,不等于0则执行exit3跳到该子程序开始位置。
改变行列坐标。
cmp指令判断小车是否超过屏幕,若没超过则执行show_string,重新置光标位置,取组成小车的字符值和字符属性,再显示在屏幕上,形成一个图形。
Loop循环locationnew_next,此时调用延时子程序使图形更加清晰,之后调用擦除子程序,使小车显示到下一个位置。
这样显示的最终结果就是小车在公路上跑。
流程图如下:
(六)定义擦除子程序erase,主要代码如下:
erase_next:
adddh,[di+2]
adddl,[di+3]
movah,2;置光标位置
int10h
moval,[di]
movbl,0;清零,小车在该位置不再显示
pushcx
movcx,1
movah,9
int10h
popcx
adddi,4;地址后移一个字符,即小车移动
looperase_next;
这是我的程序的一个小技巧,清屏的时候不是像别人那样写长串代码,而是通过重新设置显示方式来清屏,这样程序变得简单。
分别将char_cnt,pointer,line,column保存到相应的寄存器,将行地址加2,将列的地址加3,再置光标位置,将di中的值放入al,之后将bl清零,即小车就不再在该位置显示。
地址后移一个字符,这样就实现了小车的移动。
再执行loop循环,使小车能在公路上跑。
(七)定义延时子程序delaytime
主要代码如下:
delaytimeprocnear;延时子程序
pushcx
pushdx
movdx,20000;最大到65530
dly1:
movcx,1000;延时时间
dly2:
loopdly2
decdx
jnzdly1
设置小车延时1秒,dx每次自减1,当dx不等于0时则进行loop循环该部分,否则返回。
此处可以通过改变延时时间来改变小车运动的速度
程序运行结果主界面如图所示
公路下移并改变颜色,如下图
五、总结及心得
一周的课程设计,让我基本上掌握了子程序的调用与运用;它不但大大减化了程序代码,使程序的逻辑性大大加强。
汇编语言是一门与硬件直接打交道的语言,因此很多操作功能的使用需要反复调用,为此,程序显得十分烦琐,通过子程序的调用,可将这些重复的步骤,加以简化,为内存节省空间。
可是,子程序也有弱点,它的形式参数只能为操作数与地址,当数据交错时,容易出错,于是又引入了一个概念:
宏。
宏必须先定义,后调用,它的形式参数比较灵活,但是它不能节省空间。
因此,我们常常要用宏与子程序相互联系起来。
使我们的程序不断的优化,达到更好的效果,此外,对于数据缓冲区里的内部结构了解掌握也是非常重要的,这将是一个飞跃,因为它会使得我们对数据的处理更加的精准。
通过编程和对编程过程中遇到的问题的思考,有效的提高了我对汇编的认识和理解,切实的提高了我的编程能力,补全了我的不足。
通过这次课程设计,我巩固所了学过的知识,能用汇编语言熟练地运用顺序、选择、循环三大结构,进一步掌握了各个指令的功能,特别是转向指令,以及正确地运用DEBUG指令。
在整个程序的编写中,调试占了很大部分的时间。
要想写好汇编语言的程序,必须认真对待代码的每一个细节,还必须熟练的掌握debug命令,这对程序的调试是非常重要的。
通过这次实际动手能力的培养,我进一步熟悉了汇编语言的结构和使用方法,基本达到能独立阅读、编制和调试一定规模的汇编语言程序的水平。
设计过程中暴露出了自己的一些问题,动手和实践能力不足,知识上还有许多漏洞,缺乏大型程序的开发经验,理论联系实际的能力更有待提高。
希望随着以后设计的增多,阅历的增长,能够逐渐弥补这些不足
对我而言,知识上的收获重要,精神上的丰收更加可喜。
以前特别讨厌编程,坐在电脑前面就头疼,根本找不到方法,这次之后我体会到,原来自己看懂程序之后再修改,会有很大的成就感,很开心。
也让我知道了学无止境的道理,我们每一个人永远不能满足于现有的成就,人生就像在爬山,一座山峰的后面还有更高的山峰在等着你。
挫折是一份财富,经历是一份拥有。
这次课程设计必将成为我人生旅途上一个非常美好的回忆!