汇编语言程序设计打字练习程序.docx
《汇编语言程序设计打字练习程序.docx》由会员分享,可在线阅读,更多相关《汇编语言程序设计打字练习程序.docx(23页珍藏版)》请在冰点文库上搜索。
汇编语言程序设计打字练习程序
汇编语言课程设计报告
(2014--2015年度第1学期)
专业
xxx
学生姓名
xxxx
班级
xxx
学号
xxxx
指导教师
xxx
完成日期
xxxxx
1.设计目的与设计要求
一.设计目的
本课程设计是在学完教学大纲规定的全部内容、完成所有实践环节的基
础上,旨在深化学生学习的汇编语言课程基本知识,进一步掌握汇编语言程
序设计方法,提高分析问题,解决问题的综合应用能力。
设计要求
在缓冲区预放了一些字母,运行时,可按照屏幕上显示的字母输入练习,
每输入完一行按回车键后,可显示出练习输入的时间。
设计思路
1.系统总体分析
在缓存区预放了一些字母,运行时可按照屏幕上显示的字母输入练习,每输入完一行按回车键后,可显示出练习输入的时间。
当一个句子分析完后(回车键作为结束符),屏幕上以min:
sec:
msec的格式显示出键入字符的时间。
在每次打字之前,屏幕上先显示一个例句,然后打字员按照例句,将句中字符通过键盘输入。
这个过程共进行五次,当键入一个enter键时,推出打字计时练习程序。
在键盘上联系的打字例句及其他地址表,计时单位等预存在DATA数据段中。
自编的中断程序Kbint检测按键时产生的中断,并将按键扫描码转换为ASCII码存入缓存区BUFFER(内存中一个区域),这个工作和EOM09类型的键盘中断例行程序所完成的工作大致相同,只是在解释各个键时作了简化,即只解释了可显示字符(如英文小写字母,数字及一些字符),其他特殊键(如组合键,双态键,功能键),都未做解释,只做字符码0来处理。
在主程序部分保存原有09类型的中断向量,设置自编例行程序的中断向量,设置中断屏蔽位,然后在开断。
当键盘中断处理后,主程序安排指令读取缓存区中的字符并显示在屏幕上。
在主程序的末尾,利用DOS功能恢复原09类型的中断向量,然后返回DOS。
在显示键入的字符时,还应判断字符是否为回车符。
说明一个句子输入完毕,此时调用显示时间的子程序显示打字时间,然后顺序显示一个例句。
如果所存放的例句都已显示完毕,则再次从第一个例句开始显示,直至键入某个功能(如ESC键等)退出程序,结束打字练习。
打字时间统计利用自编的计时器中断处理程序Clint来完成。
每输入一个例句,计时一次。
在此中断例行程序中,定时器中断的次数记录在计数单位count中,当count的计数单位为18时,sec计数单位加1,当sec计数值达到60时,min计数单位加1,因为输入一个句子无论如何不会达到小时级,所以hours计数值得调整判断,实际上只起到退出计时器的作用。
加入一个显示菜单程序,使得原来的程序具有观赏性;显示时间的子程序disptime分别将各计时单位的二进制数转化为十进制,并以min:
sec:
msec的形式出来。
其中msec是由count中的计数值转化成的。
Count*1s/18.2=count*55ms
此式中,18.2是计算机系统中产生的一个中断,每秒18.2次。
2.主模块框图
程序的核心模块是打字计时,通过显示的例句进行打字练习,最后显示打字时间,主题流程图如下:
a.建立汇编源程序—通过b.编译为目标文件——d.连接执行文件
c.不通过,重新修改(语句错误)e.运行
f.不正确,用调试工具调试,重新修改(逻辑错误)
g.正确完成
2程序流程图
2.1主程序流程图
、
图1主程序流程图
主程序的流程图如图1所示:
说明:
首先定义堆栈段,数据段,代码段等,初始化。
显示提示信息提示打字练字的规则,说明如何开始,如何退出等。
显示出字符串后,开始读取系统时间并保存。
然后输入字符串存到指定的缓冲区。
输入结束后,再次读取系统时间,并由两次所读取的时间计算出输入字符串所用的时间并显示。
调用正确率计算函数,并显示在屏幕上。
看输入字符串对应位正确的个数是不是十个,如果是十个,则继续往下,看输入的是不是退出键1,如果是,则退出。
如果不是,则继续下一串字符的练习。
如果输入正确的个数不是十个,则返回继续该字符串的练习,指导最后输入的正确个数是十个。
2.2时间计算流程图
计算时间的流程图如图3所示:
说明:
第一次读取系统时间后,分和秒分别存在了second和minutes里,第二次读取系统时间后,比较DH里的内容和second里的内容,比较结果是second里的内容比较小,则不用向分借位,直接进行减法运算,并把计算结果转换成ASCII码并在屏幕上显示。
如果比较的结果是second里的内容是比较大,则进行减法运算时,要向分借位,所以,将DH寄存器的内容加上60,再与second里的内容进行减法运算,最后把运算结果转化成ASCII码,并显示在屏幕上。
图3时间计算流程图
2.3正确率计算流程图
正确率显示函数的流程图如图4所示:
说明:
调用争取率判断子程序,首先保护现场,BX指向字符串ADDRESS[SI]首地址,BX+2,指向第一个要显示的字母,DI指向输入缓冲区的首地址,CX寄存器存入十,控制循环次数。
比较[BX]HE[DI]里的内容,即判断显示的和输入的字母是否相同。
如果相同,计数寄存器AL内容则加一,BX加一,DI加一,继续下次比较,直到十次循环结束。
如果不相同,则计数寄存器AL内容不变,BX加一,DI加一,继续下一次循环,知道十次循环结束。
当十次循环结束后,即字符串输入结束后,寄存器AL里的内容就是输入正确的个数,AL高四位是输入正确数的十位,低四位是输入正确数的个位,将十位和个位分别转化成ASCII码,并将其存入字符串中,调用DOS的9号功能输出字符串,输出的就是屏幕显示的字符串和输入的十位字符串对应位相同的个数,然后恢复现场。
每调用一次正确率判断函数,SI加二,即第一次调用该子程序屏幕上显示的是第一组字符串,第二次调用,当SI大于5时,就退出程序。
图4正确率显示函数的流程图
3.设计关键问题
在打字练习汇编语言程序设计中,主要有三个问题,分别为输入和输出问题、输入字符串时间的计算、正确率的判断。
3.1输入输出
3.1.1输出显示信息
输出字符串,主要是利用DOS的9号功能调用。
当开始打字练习时,要输出提示信息说明打字练习时的规则,其程序为:
messagedb0ah,0dh,'WelcometoWUHANUUIVERSITY,Pleasetype10letters,andyoumustinput10rightwords,thenpressanykeytopracticethenextone'
db0ah,0dh,'ifyouwanttoquit,press1',0ah,0dh,'$'
leadx,message
movah,9
int21h
显示信息输出后,要显示预先存在缓冲区的三组字符串,显示字符串用DOS9号调用,其程序为:
str1db0ah,0dh,'wuhanunive'
db0dh,0ah,'$'
str2db0ah,0dh,'hubeichina'
db0ah,0dh,'$'
str3db0ah,0dh,'qmpzwmoxid'
db0ah,0dh,'$'
addressdwstr1,str2,str3
movdx,offsetaddress[si]
movah,9
int21h
只有当输入的字符串中的十个字符全部正确时,则显示进入下一字符串的练习并输出鼓励语,其程序为:
etdb0dh,0ah,'Congratulations,Welldone!
',0ah,0dh,'$'
movdx,offsetet
movah,09h
int21h
当要显示输入字符串所用的时间以及显示输入字符串个数时,可以采用单个字符的输出,但是为了在屏幕上看起来直观,就把要显示的时间和正确个数的十位和个位分别存在缓冲区,并把缓冲区的内容采用9号调用输出在屏幕上,其程序为:
(1)显示输入字符所用的时间的程序
timedb2dup(?
),'$'
movtime[0],ah;输入字符串所用时间的十位送入time[0]
movtime[1],al;输入字符串所用时间的个位送入time[1]
movdx,offsettime;显示time中的内容
movah,9
int21h
(2)显示输入字符串正确个数的程序为:
numdb2dup(?
),'$'
movnum[0],bh;输入字符串正确个数的十位送入num[0]
movnum[1],bl;输入字符串正确个数的个位送入num[1]
movdx,offsetnum;显示num中的内容
movah,9
int21h
3.1.2输入十个字符
当屏幕显示出要练习字符串时,就要输入十个字符存到指定的缓冲区中,使用DOS1号功能调用,其功能是输入单个字符,输出参数是AL=输入字符的ASCII码,循环十次,将十个字符存入指定的缓冲区buff中,其程序为:
buffdb15dup(?
)
movcx,10;cx=10,控制循环次数
movbx,0
again:
movah,1;输入单个字符
int21h
movbuff[bx],al;将输入的字符存到指定的缓冲区
incbx
loopagain
3.2输入字符串所用时间计算
对输入字符串时间的计算,需要知道输入字符串前的时间和输入字符串后的时间,将两者相减,即得输入字符串所用的时间。
具体为:
当显示第一串字符串后,调用DOS的2CH号功能读取系统时间,读取完系统时间后,系统时间的时、分和秒分别存在寄存器CH、CL、DH中。
并将CL和DH的内容保存到minutes和second中,以便计算输入字符串所用时间用;第一次读取系统时间后,开始输入10个字符,当输入字符结束后,再次读取系统时间,首先第二次的分钟数减去第一次的分钟数,如果结果大于零,则用第二次的秒数减去第一次的秒数,所得的结果转化称ASCII码显示在屏幕上,即为输入字符串所用的时间。
如果第二次的分钟数减去第一次的分钟数的结果小于零,则第二次的秒数加上60后,再减去第一次的分钟数,所得结果妆化称ASCII码后显示在屏幕上,则为输入字符串所用的时间。
计算输入字符串所用的时间,其程序为:
time1db'thetimeyouhavespentis:
','$'
time2db'second','$'
timedb2dup(?
)
movah,2ch;读取系统时间,时分秒分别存在CHCLDH
int21h
movminute,cl;保存第一次系统时间的分和秒
movsecond,dh
movah,2ch;读取系统时间
int21h
subcl,minute;计算输入字符串所用时间
movminute,cl
cmpdh,second
jba2
jmpgettime
a2:
adddh,60
decminute
gettime:
subdh,second
movsecond,dh
leadx,time1
movah,09h
int21h
calltimechange;调用timedchange
movtime[0],ah
movtime[1],al
movdx,offsettime;显示输入10个字符所用时间
movah,9
int21h
leadx,time2
movah,09h
int21h
3.3正确率判断
正确率的判断前提是,首先要有比较的对象,题目中给定的字符串,其次要有练习者输入的字符串,并且要存到指定的即缓冲区,然后,用两个寄存器分别指向要比较和被比较字符串的首地址,首先比较第一个字符是不是相等,如果相等,计数寄存器加一,两指针寄存器各自加一,开始下一轮比较,知道十次比较结束,将计数寄存器的内容转化称ASCII码输出,结果即为输入字符的正确数。
其程序如下所示:
judgeprocnear
pushcx;保护现场
pushdx
xoral,al
lop:
movbx,offsetaddress[si];bx指向address[si]的首地址
addbx,2
movdi,offsetbuff;di指向buff的首地址
movcx,0bh
lp2:
movdl,[bx];看[bx]和[di]的内容是否相同
cmpdl,[di]
jnznext1
incal;计数寄存器加一
next1:
incbx
incdi
looplp2
cbw
movcl,10
divcl
movbl,ah;保存余数
movdl,al;将商转化称ASCII码
adddl,30h
movbh,dl
movdl,bl;将余数转化称ASCII码
adddl,30h
movbl,dl
xoral,al
popdx;恢复现场
popcx
ret
judgeendp
4.调试运行结果分析
当汇编连接运行完程序后,屏幕显示如图5所示:
其显示的是提示信息以及第一串字符串wuhanunive,等待进行打字练习者从键盘输入10个字符。
图4编译连接运行结果
当打字练习者从键盘输入10个字符后,第二次读取系统时间后,计算出输入10个字符所用时间并显示,计算出正确率并显示在屏幕上。
当输入的10个字符为wuhanyuniv时,输入正确的个数应该为5个,输入后,屏幕显示结果如图6所示,正确率为5,所用时间为4秒,结果正确。
由于正确率不是10个,所以下一组练习还应为第一组字符串wuhanunive的练习,即正确率显示结束后所显示的下一组字符练习仍为wuhanunive,图5显示的结果正式如此。
图5输入不完全真确的10个字符运行结果
当输入10个完全正确的字符后,显示时间后,还显示输入正确的个数为10,并显示出提示语,提示练习者可以进行下一组字符串的联系了,同时显示出下一组练习字符为第二组字符串hubeichina,结果如图6所示:
图6输入10个完全正确字符显示结果
第一组的10个字符完全输入正确后,如果想退出练习,则按1,退出练习;若想继续下一组练习,则按任意键,屏幕上自动直接显示出第二组要练习的字符串hubeichina,开始第二组打字练习,同上,第二组字符输入完全正确后,按1可以退出,按任意键进行第三组打字练习,就不再赘述。
第二组打字练字屏幕显示结果如图7所示:
图7第二组字符串练习
5心得体会
到这一刻为止,汇编课设就接近尾声了,有兴奋,也有惶恐,兴奋的是任务终于完成了,同时也很担心,自己还站在汇编语言的门口,只是一个初学者。
在课程设计的过程中,深刻地觉得汇编语言真的是很神奇,不过这也从侧面说明自己对汇编语言了解的不多。
通过本次的《汇编语言程序设计》课程设计,真的学到了很多东西。
是对这学期所学的《汇编语言程序设计》知识的一个综合和提升。
在这次课程设计中,最重要的是编制汇编语言程序的调试。
通过这次课程设计,我对汇编语言的调试有了很深刻的了解,当程序出错时,主要是通过调试来找出程序中的错误,当然在调试过程中,遇到很多困难,主要是平时练习不够,没有注意培养汇编语言的调试练习,在做实验时,忽略了对程序的调试。
微机的应用已渗透到生活中的方方面面,利用微机,以前难以实现的东西轻而易举地成为现实。
所以,作为工科学生,要了解微机的内部结构、系统构成、指令系统、输入输出接口、存储器和接口的扩展等等,这些对我们来说非常重要。
汇编语言程序设计的方法和多模块程序设计。
作为最基本的编程语言之一,汇编语言的重要性勿庸置疑,因为它能够完成许多其它语言所无法完成的功能。
尤其在和硬件关系非常密切的程序或要提高运算速度的程序,即使是C语言也会有些力不从心,而汇编语言则能够很好扬长避短,最大限度地发挥硬件的性能。
这次汇编语言程序设计历时九天,在整整九天的日子里,可以说是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,还学到了很多在书本上所没有学到过的知识。
还有我意识到画程序方框图是很有必要的。
因为通过程序方框图,在做设计的过程中,我们每一步要做什么,每一步要完成什么任务都有一个很清楚的思路,而且在程序测试的过程中也有利于查错。
不仅如此,以前对于编程工具的使用还处于一知半解的状态上,但是经过一段上机的实践,对于怎么去排错、查错,怎么去看每一步的运行结果,怎么去了解每个寄存器的内容以确保程序的正确性的认识上都有了很大程度的提高。
总之,这次课程设计让我受益匪浅,使我更加深入地理解了汇编语言程序设计上讲到的各种芯片的功能,以及中断调用,同时加深了对于主要芯片的应用的认识,同时也更加清楚了汇编程序的编写过程和运行过程。
这不仅加深和巩固了我们的课本知识,而且增强了我们自己动脑,自己动手的能力。
参考文献
[1]周佩玲,彭虎,傅忠谦编著.汇编语言程序设计(基于16位机).北京:
电子工业出版社,2005
[2]张雪兰,谭毓安,李元章编著.汇编语言程序设计(从DOS到Windows).清华大学出版社,2006
[3]杨季文等编著.80x86汇编语言程序设计教程.清华大学出版社,1998
[4]马力妮.80x86汇编语言程序设计.北京:
机械工业出版社,2004
[5]曹加恒,苏光奎,许先斌.新一代汇编语言程序设计.北京:
高等教育出版社,2003
附录
附录一打字计时练习程序
stacksegmentparastack'stack'
db256dup(0)
stackends
datasegment
messagedb0ah,0dh,'WelcometoWUHANUUIVERSITY,Pleasetype10letters,andyoumustinput10rightwords,thenpressanykeytopracticethenextone'
db0ah,0dh,'ifyouwanttoquit,press1',0ah,0dh,'$'
strdb0ah,0dh,'$'
str1db0ah,0dh,'wuhanunive'
db0dh,0ah,'$'
str2db0ah,0dh,'hubeichina'
db0ah,0dh,'$'
str3db0ah,0dh,'qmpzwmoxid'
db0ah,0dh,'$'
addressdwstr1,str2,str3
time1db'thetimeyouhavespentis:
','$'
time2db'second','$'
numberdb'therightnumberis:
','$'
buffdb15dup(?
)
minutedb(?
)
seconddb(?
)
timedb2dup(?
),'$'
numdb2dup(?
),'$'
etdb0dh,0ah,'Congratulations,Welldone!
'
db0ah,0dh,'$'
dataends
codesegment
assumecs:
code,ds:
data,ss:
stack
start:
movax,data
movds,ax
leadx,message;显示提示信息
movah,9
int21h
movsi,0
lp1:
movdx,offsetaddress[si];显示给定字符串
movah,9
int21h
movah,2ch;读取系统时间
int21h
movminute,cl;保存第一次系统时间的分和秒
movsecond,dh
leadx,str;显示回车换行
movah,09h
int21h
movcx,10;cx=10,控制循环次数
movbx,0
again:
movah,1;输入单个字符
int21h
movbuff[bx],al;将输入的字符存到指定的缓冲区
incbx
loopagain
leadx,str
movah,09h
int21h
movah,2ch;读取系统时间
int21h
subcl,minute;计算输入字符串所用时间
movminute,cl
cmpdh,second
jba2
jmpgettime
a2:
decminute
adddh,60
gettime:
subdh,second
movsecond,dh
leadx,time1
movah,09h
int21h
calltimechange;调用timechange子程序
movtime[0],ah;保存输入字符所用时间的十位送入
movtime[1],al;保存输入字符所用时间的个位
movdx,offsettime;显示time中的内容
movah,9
int21h
leadx,time2
movah,09h
int21h
leadx,str
movah,09h
int21h
movdx,offsetnumber
movah,9
int21h
calljudge
movnum[0],bh;保存输入正确个数的十位
movnum[1],bl;保存输入正确个数的个位
movdx,offsetnum;显示num中的内容
movah,9
int21h
cmpbh,31h
jnzlp8
movdx,o