北邮微原作业中断实验与编程分析.docx
《北邮微原作业中断实验与编程分析.docx》由会员分享,可在线阅读,更多相关《北邮微原作业中断实验与编程分析.docx(14页珍藏版)》请在冰豆网上搜索。
北邮微原作业中断实验与编程分析
微原第二次软件实验
一、实验要求
编写一程序,在显示器上显示时、分、秒。
具体要求如下:
1)借用计数器8253的Timer()作为中断源,通过8259A向CPU发中断,每10ms产生一次中断;
2)在中断服务程序中管理刷新时、分、秒;
3)输入文件名后清屏显示:
Currenttimeis:
XX:
XX:
XX(时、分、秒键盘输入);
4)当键入CTRL+C时,停止计时,返回系统,且系统正常运行不死机。
二、设计思路
1)数据段定义四个字符串,分别用于显示程序功能、提示用户输入,显示当前时间以及错误格式输入提示。
同时定义六个变量用于存储当前显示的的时、分、秒的十位及个位,一个变量count100用以中断计数;
2)在BIOS功能调用中,令AH=6,设置窗口左上角、右下角行列位置使当前页上滚,从而实现程序一开始的清屏功能;
3)提示用户输入起始时间时,需要对输入格式进行判断,严格要求输入在00:
00:
00至23:
59:
59,正确输入时则存入相应的变量中,输入任意键开始计时,错误时则屏幕显示输入错误,提示用户重新进行输入,若输入为“CTRL+C”时退出程序;
4)利用8253作为中断源,输入控制字36H,时间常数为11932,使其选用通道0计数,产生频率100Hz的方波,即中断100次时间间隔为1s,时间刷新显示;
5)8253中断源每中断一次,进入timer中断子程序,将其段基地址及段内偏移量存入中断向量表,利用8259向CPU发出中断;
6)timer子程序会对中断次数进行判断,每中断满100次时根据当前时间进行相应的时、分、秒修改,若不满100次时直接退出中断;
7)屏幕显示时将时、分、秒的十位和个位分别送人al中,在BIOS功能调用中令ah=14h,实现将al中的字符写到光标位置,并将光标进一,8次循环直到时钟完全显示,同时比对second,中断满100次时,即时间间隔1s时second变化,当检测到这一变化时重新进入disp刷新显示;
8)在每秒变化需要刷新显示时,都先进行键盘输入判断,当有输入且输入为“ctrl+c”时,退出程序。
三、程序流程
1)主要程序流程图
2)中断程序流程图
四、源代码
datasegment
count100db100
tenhourdb0
hourdb0,':
'
tenmindb0
minutedb0,':
'
tensecdb0
seconddb0
s1db'(00:
00:
00~23:
59:
59"Ctrl+C"toexitkeytostart)$'
s4db'Startingtimeis:
$'
s2db'("Ctrl+C"toexit)Currenttimeis:
$'
s3db'Error!
',0dh,0ah,'$'
dataends
stacksegmentstack
db256dup(0)
stackends
;回车换行宏定义
CRLFMACRO
movah,02h
movdl,0dh
int21h
movdl,0ah
int21h
ENDM
codesegment
assumeds:
data,cs:
code,ss:
stack
start:
movax,data
movds,ax
moves,ax
;清屏
moval,0;整个窗口为空白
movch,0;窗口左上角的行位置
movcl,0;窗口左上角的列位置
movdh,24;窗口右下角的行位置
movdl,79;窗口右下角的列位置
movbh,7;正常显示属性
movah,6;当前显示页上滚功能调用号
int10h;I/O中断调用
begin:
movdx,offsets1
movah,09h;程序提示
int21h
CRLF
movdx,offsets4
movah,09h;提示输入
int21h
movbp,0;分输入正确后加一,跳转为秒输入判断
movdi,offsettenhour
movah,01h
int21h
cmpal,03h
jnzgoon1;读取第一位,不为ctrl+c则继续键入
movah,4ch
int21h
goon1:
movbl,'0';第一位为0到2
cmpal,bl
jltiaoban
movbl,'2'
cmpal,bl
jgtiaoban
mov[di],al;存入tenhour
movbh,al
incdi
movah,01h
int21h
cmpal,03h
jnzgoon2;读取第二位,不为ctrl+c则继续键入
movah,4ch
int21h
goon2:
cmpbh,'2';如果第一位为2,则第二位为0到3
jetenhour2
movbl,'0';第二位为0到9
cmpal,bl
jltiaoban
movbl,'9'
cmpal,bl
jgerror
mov[di],al;存入hour
jmpnextchar
tiaoban:
jmperror;用于跳转
tenhour2:
movbl,'0'
cmpal,bl
jlerror
movbl,'3'
cmpal,bl
jgerror
mov[di],al
nextchar:
incdi
movah,01h
int21h
cmpal,03h
jnzgoon3;读取第三位,不为ctrl+c则继续键入
movah,4ch
int21h
goon3:
movbl,':
';第三位为‘:
’
cmpal,bl
jneerror
incdi
movah,01h
int21h
cmpal,03h
jnzgoon4;读取第四位,不为ctrl+c则继续键入
movah,4ch
int21h
goon4:
movbl,'0';分、秒均为00-59
cmpal,bl
jlerror
movbl,'5'
cmpal,bl
jgerror
mov[di],al;存入tenmin或tensec
incdi
movah,01h
int21h
cmpal,03h
jnzgoon5;读取第五位,不为ctrl+c则继续键入
movah,4ch
int21h
goon5:
movbl,'0'
cmpal,bl
jlerror
movbl,'9'
cmpal,bl
jgerror
mov[di],al;存入minute或second
incbp
cmpbp,1;bp为1则继续读取秒钟输入
jenextchar
signal:
movah,0bh;输入任意键开始计时
int21h
oral,al
jzsignal;无输入继续检测,有输入才开始
CRLF;换行回车
jmpinit
error:
movdx,offsets3
movah,09h
int21h;显示错误提示信息
JMPbegin;重新读取
init:
cli;关中断
movax,0
moves,ax;置附加段基地址为0
movdi,20h;中断号08h*4
movax,offsettimer;中断程序的段内偏移量
stosw;偏移量存入中断向量表
movax,cs;中断程序段基地址
stosw;段基地址存入中断向量表
moval,36h;选用0通道计数器,采用3号方式(方波)计数
out43h,al
movbx,11932;时间常数,输出100HZ方波
moval,bl
out40h,al
moval,bh
out40h,al
moval,0fch
out21h,al;21h端口为中断屏蔽寄存器,用以开发外部中断
sti;开中断
;屏幕显示当前时间,变化时刷新显示
disp:
movah,0bh
int21h
oral,al
jznoexit;系统无输入时不退出
movah,08h
int21h
cmpal,03h
jnznoexit
movah,4ch
int21h
noexit:
movdx,offsets2
movah,09h
int21h
movbx,offsettenhour
movcx,8
dispclk:
moval,[bx]
calldispchar
incbx
loopdispclk;时分秒存入al并显示
moval,0dh
calldispchar
moval,second;时间变化时秒个位必变化
next:
cmpal,second
jenext;无变化时循环
jmpdisp;有变化时刷新显示
;中断一百次即为1s,时间相应变化
timerprocfar
pushax
deccount100
jnztimerx
movcount100,100
incsecond
cmpsecond,'9';小于等于9,即之前秒个位为0-8
jletimerx;秒个位0-8,变化后秒个位加1显示即可
movsecond,'0';原个位为9,变化后为0
inctensec
cmptensec,'6'
jltimerx;加1后小于5,即原秒十位为0-4,十位加1即可显示
movtensec,'0'
incminute;与秒同理
cmpminute,'9'
jletimerx
movminute,'0'
inctenmin
cmptenmin,'6'
jltimerx
movtenmin,'0'
inchour
cmptenhour,'2'
jlnexth
cmphour,'3'
jletimerx
movhour,'0'
movtenhour,'0'
jmptimerx
nexth:
cmphour,'9'
jletimerx
adjhour:
inctenhour
movhour,'0'
timerx:
moval,20h
out20h,al
popax
iret;中断退出
timerendp
dispcharproc
pushbx
movah,14;写字符到光标位置,光标位置加1
int10h
popbx
ret
dispcharendp
codeends
endstart
五、子程序清单
1)子程序名:
timer;
功能:
判断中断计数是否满100次,若已满对时间做出相应的修改;
入口参数:
无;
出口参数:
无;
使用寄存器:
AX,FR。
2)子程序名:
dispchar;
功能:
写入相应字符至光标位置,并将光标前进一位;
入口参数:
al,用以存储待写入的字符;
出口参数:
无;
使用寄存器:
AX,BX。
六、程序分析
1)本程序一开始利用INT10H进入BIOS功能调用,通过当前页上滚实现清屏功能,采用用户键入得到现行时钟起始值,利用INT21H读取用户键盘输入,等待用户正确输入后开始计时;
2)利用8253作为中断源,43H端口是8253三通道定时器中的命令寄存器,所使用的命令字36H表示选用0通道定时器,以3号方式(产生方波)计数。
向端口40H送出的计数器初值选用11932是要求8253每秒发出100次时钟中端(08H),将本程序中的timer的起始地址送入中断的入口地址,保证每次发生08H中断时,程序自动进入timer;
3)程序运行的大体过程为:
主程序显示时钟值,发生中断08H时进入timer,查看中断计数是否达到100次,若没有达到次数直接退出中断返回主程序;若已达到,则时间又过了1s,对个数据进行修改后返回主程序;
4)本程序的时钟显示范围是00:
00:
00至23:
59:
59,因而在计时至23:
59:
59时,下一秒将时间修改为00:
00:
00,针对不同的时间改变过程,程序中做了对应的修改,已保证时钟显示无误,在输入过程及刷新显示时对键盘输入进行检测,当输入“CTRL+C”时退出程序。
七、执行结果
1)初始清屏,提示用户输入正确时间:
2)输入错误时提示错误输入:
3)正确输入时开始计时:
4)输入“ctrl+c”时退出程序:
八、实验总结
通过本次实验,初步掌握了中断的应用,在编写过程中,出现逐位判断异常,跳转超出范围,中断程序写入异常的问题,通过查阅书本及翻阅相关资料,解决了上述问题。
本次实验与之前实验相比难度有所提升,完成程序的过程中对各中断号的应用更为熟练,汇编语言的编写能力逐步提升。