汇编实验11.docx
《汇编实验11.docx》由会员分享,可在线阅读,更多相关《汇编实验11.docx(8页珍藏版)》请在冰豆网上搜索。
汇编实验11
山东大学实验报告
2016年月日
姓名刘方铮,学号201411130001系年级计算机科学与技术系2014级
科目汇编语言题目中断练习程序
实验源程序清单
中断练习程序:
showmacrobuf
pushdx
leadx,buf
movah,9
int21h
popdx
endm
datasegment
keep_ip1dw?
;保存9号中断偏移地址
keep_cs1dw?
;保存9号中断段地址
keep_ip2dw?
;保存1ch号偏移地址
keep_cs2dw?
;保存1ch号段地址
bufferdb'Thereisainterruption!
',0dh,0ah,'$'
buffer1db'Noring,butwaitingforinterrupt',13,10,'$'
buffer2db'Thebellisring!
',13,10,'$'
buffer3db'Recoverymainprogramandring!
',13,10,'$'
buffer4db'Hangonmainprogramandring',13,10,'$'
flagdb0
countdw?
dataends
codesegment
mainprocfar
assumecs:
code,ds:
data
start:
pushds
subax,ax
pushax;
movax,data
movds,ax
movcount,1
;保存原中断向量(9号中断向量)(实验书107页
(1))
moval,09h;取中断类型09h
movah,35h;取中断向量功能调用
int21h
movkeep_cs1,es;保存段地址
movkeep_ip1,bx;保存偏移地址(为保存原中断向量)
;设置新的中断向量(9号中断向量)(实验书107页
(2))
pushds
movdx,offsetkeyboard;存储偏移地址
movax,segkeyboard;存储段地址
movds,ax
moval,09h;中断类型9:
键盘中断
movah,25h;25号功能:
设置中断向量
int21h
popds
;保存原中断向量(1ch号中断向量)(实验书107页
(1))
moval,1ch;取中断类型1ch:
定时器控制的软中断
movah,35h;取中断向量功能调用
int21h
movkeep_cs2,es
movkeep_ip2,bx
;设置新的中断向量(1ch号中断向量)(实验书107页
(2))
pushds
movdx,offsetring;存储偏移地址
movax,segring;存储段地址
movds,ax
moval,1ch
movah,25h
int21h;设置新的中断向量
popds
;允许键盘和定时器中断(通过控制对21h端口的各位分别置0或1来控制中断级是被允许还是禁止)
inal,21h
andal,11111100b
out21h,al
sti
lop:
jmplop
;恢复原来的中断向量(9ch中断),否则后续程序不能正确使用系统提供的例行程序(实验书108页(3))
pushds
movdx,keep_ip1
movax,keep_cs1
movds,ax
moval,09h
movah,25h
int21h
popds
;同上,这段是用来恢复1ch号中断(实验书108页(3))
pushds
movdx,keep_ip2
movax,keep_cs2
movds,ax
moval,1ch
movah,25h
int21h
popds
ret
mainendp
;#########################################################################
;响铃子程序,参看书本P286页,有详解#
;#########################################################################
ringprocnear
pushds
pushax
deccount
jnzexit
showbuffer2;buffer2:
'Thebellisring!
'
movdx,5000
inal,61h;
andal,11111100b;这两句话目的是让设备控制寄存器的末两位都变成0
sound:
xoral,02;第1位由0变为1,继续执行下去后又由于循环而回到这句,此时第1位由1变为0,
out61h,al;而端口61H的第1位和扬声器的脉冲门相连,当第1位由0变为1,延迟一会又由1变为0时,脉冲门就先打开后关闭,产生了一个脉冲电流。
这个脉冲电流被放大后送到扬声器使之发出声音
movcx,6000h;这个循环语句就是所谓的延迟一会
wait1:
loopwait1
decdx
jnesound
movcount,91;CPU能响应定时器每秒18.2次的中断请求,5秒的话就是91次,前面有一句是deccountjnzexit,也就是说当91一直减,减到0时才发声,这样就可以起到5秒响铃一次的效果。
exit:
popdx
popax
iret
ringendp
;############################################################################
;对中断判断转入不同处理(实验书117页)#
;############################################################################
keyboardprocnear
pushax
inal,60h;读键盘
pushax;保存扫描码
inal,61h
oral,80h
out61h,al;置键盘应答位
inal,61h;输入应答位
andal,7fh;01111111
out61h,al;复位键盘应答位
popax
testal,80h;是否“通码”
jnzinkret;不是则中断返回
xorflag,1;是则触发标志位
cmpflag,1;第一次按键?
jeprocess1;是则挂起主程序和响铃
process2:
;第二次按键,恢复主程序及响铃
inal,21h
andal,11111100b
out21h,al
showbuffer3
jmpinkret
process1:
;挂起主程序及响铃
showbuffer4
inal,21h
oral,01h;屏蔽定时器中断
out21h,al
showbuffer
moval,20h;结束第一次键盘中断
out20h,al
sti;允许再次中断
again:
;等待第二次键盘中断
cmpflag,1
jeagain
inkret:
;中断结束命令
moval,20h;
out20h,al;清除当前中断级
sti
popax
iret
keyboardendp
;#################################################################
codeends
endmain
运行结果:
问题及收获
通过中断练习,熟悉了存储器中缓冲区的运用,加深了操作系统中线程中断挂起等待调用的理解,有意思的地方是通过读取扫描码的最高位判别按键(第一次,第二次)和放开键