收藏 分享(赏)

第一章课程设计一.doc

上传人:dcjskn 文档编号:4357913 上传时间:2018-12-24 格式:DOC 页数:9 大小:479KB
下载 相关 举报
第一章课程设计一.doc_第1页
第1页 / 共9页
第一章课程设计一.doc_第2页
第2页 / 共9页
第一章课程设计一.doc_第3页
第3页 / 共9页
第一章课程设计一.doc_第4页
第4页 / 共9页
第一章课程设计一.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、1第一章 课程设计一一、设计题目要求编制实现以下功能的中断程序:在主程序运行期间 ,每 5 秒钟响铃一次;当键盘上的某个键被按下时,主程序和响铃都被挂起,显示器显示 buffer 缓冲区中的字符串,然后等待下一次按键引起的键盘中断;当键盘中断发生后,恢复主程序和响铃.这一过程可以重复任意次。二、设计思路(1)本设计需要定时器及键盘两个中断源,这两个中断源的关系是: 在主程序运行期间(可用 loop 指令作空闲循环来模拟),cpu 既能响应定时器每秒 18.2 次的中断请求,也能响应键盘的中断请求。当第一次按键产生中断后,应禁止定时器的中断,并开始显示字符串。只有第二次按键产生中断时,才恢复定时

2、器的中断并返回主程序。(2)主程序中应分别保存定时器及键盘的原中断向量,设置自编处理程序的中断向量,清除定时器和键盘的中断屏蔽位并开中断。在返回 DOS 之前,恢复定时器和键盘原来的中断向量。(3)按下键和放开键都能引起键盘中断,但在处理键盘中断时,对按键所产生的代码不必解释处理,只需根据读取的扫描码的最高位确定是按键中断还是释放键中断。如果是释放键引起的中断,则无须做任何工作,直接从中断处理程序中退出。如果是按下键引起的中断,则要区别是第一次按键还是第二次按键,以便作出不同的处理,为此可设置一个标志变量 flag。(4)每次按下键产生的中断,使 flag 的最低位发生一次变化,设 flag

3、的初始值为0,则第一次按键使其变为 1,第二次按键使其变为 0.,这样通过判断 flag 为 1 或 0来区别两次按键,并分别转入不同的处理。(5)第一次按键的处理功能是屏蔽定时器中断,使之不再控制响铃,然后等待第二次键盘中断,为此必须清除第一次按键产生的中断级。三、程序说明1、程序名称:inter2、程序功能:该程序实现:在主程序运行期间,每 5 秒钟响铃一次;当键盘上的某个键被按下时,主程序和响铃都被挂起,显示器显示 buffer 缓冲区中的字符串,然后等待下一次按键引起的键盘中断;当键盘中断发生后,恢复主程序和响铃.这一过程可以重复任意次。3、寄存器使用情况:在 main 函数部分: D

4、X 用于存放自编中断例行程序偏移地址AX 用于存放子程序入口地址的段基址DI 、SI 用作产生延迟时间的计数值AL 、AH 在取或设置中断向量功能调用时保存调用参数AL 用于 I/O 指令中在程序 timer 部分: DL 用于 2 号功能调用时保存调用参数2在程序 kbdint 部分:AL 用于 I/O 指令中 4、流程图开 始取类型号为 1CH 的原中断向量保存原中断向量段址,偏移地址程序 timer 入口地址的偏移送DX段基址送 AX设置新中断向量 1CH取中断向量 09Hkbdint 入口地址的偏移量送 DX段基址送 AX设置新中断向量 09H(键盘中断)()设置新中断向量 09H(键

5、盘中断)()设置中断屏蔽寄存器()开中断()主程序工作()清除中断允许位()清除中断允许位()恢复中断向量 1CH()恢复中断向量 09H()3YN结 束timer( count)减 1(count)=0 ?开中断设置响铃输出字符串“ Bell!”(count)=91关中断中断返回4YNNYYNkbdint从 60H 读扫描码保存扫描码 ax 入栈读 61H 端口信息置键盘应答位复位键盘应答位触发标志位将入栈的内容出栈送 ax(al)是通码?flag=1?打开键盘中断和定时器中断屏蔽定时器中断显示 buffer 中的字符串结束第一次键盘中断开中断flag=1?中断结束开中断中断返回5图 1 程

6、序 inter 的流程图四、程序清单data segment ;定义数据段开始keep_ip08 dw ? ;定义存储单元保存原中断向量keep_cs08 dw ?keep_ip09 dw ?keep_cs09 dw ?flag db 0 ;定义变量 flag 判 flag 为 1 或 0 来区别两次按键count dw 1 ;定义变量 count 初值为 1mess db 0ah,0dh,Bell!,0ah,0dh,$;定义 2 个字符串buffer db 0ah,0dh,Keyboard Interrupt!,0ah,0dh,$data ends ;数据段定义结束stack segment

7、 para stack stack;定义堆栈段开始dw 100 dup(0) ;堆栈大小为 100 个字stack ends ;堆栈段定义结束code segment ;定义代码段开始assume cs:code,ss:stack,ds:datamain proc far ;定义过程开始start: ;START 为程序执行时的启始标号mov ax,datamov ds,ax mov al,1ch ;取类型号为 1CH 的原中断向量 mov ah,35h ;取中断向量的功能调用int 21h ;段址放入 ES,偏址放入 BXmov keep_ip08,es ;保存旧向量, 存原中断向量段址mo

8、v keep_cs08,bx ;存原中断向量偏移量push ds ;保存 DSlea dx,timer ;子程序入口地址的偏移量( 自编中断例行程序偏移地址) 送 DXmov ax,seg timer ;子程序入口地址的段基mov ds,ax ;中断向量送 DS,自编中断例行程序段地址放入 DSmov al,1ch ;设置新中断向量 1c(定时器中断), 中断类型放入 ALmov ah,25h ;设置中断向量的功能调用int 21h ;设置新的中断向量,改变中断向量pop ds ;恢复 DSmov al,09h ;取中断向量 09hmov ah,35hint 21hmov keep_ip09,

9、es ;保存旧向量, 存原中断向量段址mov keep_cs09,bx ;存原中断向量偏移量push ds lea dx,kbdint ;新偏移量送 DX,设置新中断向量 09h(键盘中断)mov ax,seg kbdintmov ds,ax ;新段址送 DS,中断向量送 DS6mov al,09h ;写入新的中断向量mov ah,25hint 21hpop ds in al,21h ;设置中断屏蔽寄存器, 重新增设键盘中断和定时器中断and al,0fch ;键盘和定时器址直由第 0 和 1 位out 21h,al sti ;开中断, 设置中断允许位(IF=1),允许 CPU 响应外设中断请

10、求mov di,20000 ;其实就是一个延时dly: mov si,30000 ;延时dly1: dec si ;以下是一个双循环,就是控制程序时间jnz dly1dec di ;可以调整 si,di 的数值,如果大, 就是显示时间长jnz dly ;主程序工作(期间每秒产生中断 18.2 次)cli ;清除中断允许位(IF=0),禁止 CPU 响应任何外设中断jmp startpush ds ;保存 DSmov dx,keep_ip08 ;恢复中断向量 1chmov ax,keep_cs08mov ds,ax ;自编中断例行程序段地址放入 DSmov al,1ch ;中断类型mov ah,

11、25h ;设置中断向量int 21h ;DOS 调用pop ds ;恢复 DSpush ds ;保存 DSmov dx,keep_ip09 ;恢复中断向量 09h(键盘中断), 取出保存的偏移地址mov ax,keep_cs09 ;取出保存的段地址mov ds,axmov al,09h ;中断类型mov ah,25h ;设置中断向量int 21h ;DOS 调用pop ds ;恢复 DSmov ah,4ch ;结束程序int 21hmain endp;-timer proc nearpush dspush axpush cxpush dx ;保存所有已修改的寄存器mov ax,datamov

12、ds,ax ;数据段段始址送 DS7dec count ;给 count 减 1,就是变成 0jnz exit ;不等于 0 退出,其实等于,所以输出sti ;开中断, 允许更高级中断 mov dl,07h ;响铃mov ah,02hint 21hjmp $+2 ;两个字节, 就是下面的命令, 起到延时作用lea dx,mess ;输出提示字符串“Bell!“mov ah,09hint 21hmov count,91 ;count*1 秒/18.2=5 秒exit: cli ;关中断pop dxpop axpop cxpop ds ;恢复寄存器iret ;中断返回timer endp;-kbd

13、int proc near ;键盘中断处理程序push ax ;保存所有已修改的寄存器in al,60h ;读键盘, 从 PA(60H)口读扫描码push ax ;保存扫描码in al,61h ;读 PB(61H)口信息or al,80hout 61h,al ;置键盘应答位in al,61hand al,7fhout 61h,al ;复位键盘应答位pop axtest al,80h ;是通码?jnz inkret ;不是, 中断返回xor flag,1 ;是通码, 则触发标志位cmp flag,1 ;第一次按键?je process1 ;是, 则挂起主程序和响铃process2: ;是第二次按

14、键,则恢复主程序及响铃in al,21hand al,0fch ;打开键盘中断和定时器中断out 21h,aljmp inkretprocess1:in al,21h ;屏蔽定时器中断or al,01out 21h,al8call display_char ;显示字符mov al,20h ;结束第一次键盘中断out 20h,alsti ;允许再次中断, 开中断again:cmp flag,1 ;等待第二次键盘中断 je againinkret:mov al,20h ;中断结束命令out 20h,al ;送中断命令寄存器stipop ax ;恢复寄存器iret ;中断返回kbdint endp;

15、-display_char proc near ;定义显示字符子程序push axpush dxpush ds ;保存所有已修改的寄存器mov ax,datamov ds,ax ;数据段段始址送 DSlea dx,buffer ;显示 buffer 缓冲区中的字符串mov ah,09hint 21h pop dspop dxpop ax ;保存所有已修改的寄存器ret ;返回 DOSdisplay_char endp;-code ends ;代码段定义结束end start ;整个程序到此结束五、运行结果1、在编辑源程序之后,用汇编程序 MSAM.EXE 进行汇编(格式为 masm inter

16、;),然后用链接程序 LINK.EXE 进行链接(格式为 link inter;),最后运行程序(格式为 inter)。2、运行结果说明:存储器中有一个地址为 buffer 的缓冲区,存放着一串 ASCII 码字符“Keyboard Interrupt!” 。当运行 inter.exe 时,在主程序运行期间 ,每 5 秒钟响铃一次,且显示字符串“Bell !”; 当键盘上的某个键被按下时, 主程序和响铃都被挂起, 显示器显示buffer 缓冲区中的字符串 ,然后等待下一次按键引起的键盘中断;当键盘中断发生后,恢复主程序和响铃.这一过程可以重复任意次。9六、遇到的问题及解决的方法1、由于以前没有

17、学过有关中断服务程序的设计,所以开始时觉得无从下手,不知该怎么写程序,后来认真将书上的内容看了一遍,又看了一些例题,才着手写程序,在写的过程,还是边看书,边写程序,最后才将程序完成。2、开始没有注意区别两次按键的不同,后来知道:按下键和放开键都能引起键盘中断,但在处理键盘中断时,对按键所产生的代码不必解释处理,只需根据读取的扫描码的最高位确定是按键中断还是释放键中断。如果是释放键引起的中断,则无须做任何工作,直接从中断处理程序中退出。如果是按下键引起的中断,则要区别是第一次按键还是第二次按键,以便作出不同的处理,为此可设置一个标志变量 flag。每次按下键产生的中断,使 flag 的最低位发生一次变化,设 flag的初始值为 0,则第一次按键使其变为 1,第二次按键使其变为 0.,这样通过判断 flag 为 1 或 0 来区别两次按键,并分别转入不同的处理。七、心得体会虽然最终将这个设计题目完成了,但我觉得对于有关中断程序设计的方法还是不是很清楚,要看的东西还有很多。通过这次设计,我知道了编写中断程序要注意的地方有很多,基本掌握了用户自编中断处理程序的基本形式。中断程序设计的知识点比较多,所以,在今后的学习中,我会继续学习有关中断程序设计的方法与技能。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 中等教育 > 教学研究

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报