第一章课程设计一.doc_第1页
第一章课程设计一.doc_第2页
第一章课程设计一.doc_第3页
第一章课程设计一.doc_第4页
第一章课程设计一.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一章 课程设计一一、设计题目要求编制实现以下功能的中断程序:在主程序运行期间,每5秒钟响铃一次;当键盘上的某个键被按下时,主程序和响铃都被挂起,显示器显示buffer缓冲区中的字符串,然后等待下一次按键引起的键盘中断;当键盘中断发生后,恢复主程序和响铃.这一过程可以重复任意次。二、设计思路(1)本设计需要定时器及键盘两个中断源,这两个中断源的关系是:在主程序运行期间(可用loop指令作空闲循环来模拟),cpu既能响应定时器每秒18.2次的中断请求,也能响应键盘的中断请求。当第一次按键产生中断后,应禁止定时器的中断,并开始显示字符串。只有第二次按键产生中断时,才恢复定时器的中断并返回主程序。(2)主程序中应分别保存定时器及键盘的原中断向量,设置自编处理程序的中断向量,清除定时器和键盘的中断屏蔽位并开中断。在返回DOS之前,恢复定时器和键盘原来的中断向量。(3)按下键和放开键都能引起键盘中断,但在处理键盘中断时,对按键所产生的代码不必解释处理,只需根据读取的扫描码的最高位确定是按键中断还是释放键中断。如果是释放键引起的中断,则无须做任何工作,直接从中断处理程序中退出。如果是按下键引起的中断,则要区别是第一次按键还是第二次按键,以便作出不同的处理,为此可设置一个标志变量flag。(4)每次按下键产生的中断,使flag的最低位发生一次变化,设flag的初始值为0,则第一次按键使其变为1,第二次按键使其变为0.,这样通过判断flag为1或0来区别两次按键,并分别转入不同的处理。(5)第一次按键的处理功能是屏蔽定时器中断,使之不再控制响铃,然后等待第二次键盘中断,为此必须清除第一次按键产生的中断级。三、程序说明1、程序名称:inter2、程序功能:该程序实现:在主程序运行期间,每5秒钟响铃一次;当键盘上的某个键被按下时,主程序和响铃都被挂起,显示器显示buffer缓冲区中的字符串,然后等待下一次按键引起的键盘中断;当键盘中断发生后,恢复主程序和响铃.这一过程可以重复任意次。3、寄存器使用情况:在main函数部分: DX 用于存放自编中断例行程序偏移地址AX 用于存放子程序入口地址的段基址 DI 、SI 用作产生延迟时间的计数值 AL 、AH在取或设置中断向量功能调用时保存调用参数 AL 用于I/O指令中在程序timer部分: DL用于2号功能调用时保存调用参数在程序kbdint部分:AL 用于I/O指令中 4、流程图开 始取类型号为1CH的原中断向量保存原中断向量段址,偏移地址程序timer入口地址的偏移送DX段基址送AX设置新中断向量1CH取中断向量09Hkbdint入口地址的偏移量送DX段基址送AX设置新中断向量09H(键盘中断)()设置新中断向量09H(键盘中断)()设置中断屏蔽寄存器()开中断()主程序工作()清除中断允许位()清除中断允许位()恢复中断向量1CH()恢复中断向量09H()结 束timer(count)减1(count)=0? Y开中断设置响铃 N输出字符串“Bell!”(count)=91关中断中断返回kbdint从60H读扫描码保存扫描码ax入栈读61H端口信息置键盘应答位复位键盘应答位将入栈的内容出栈送ax(al)是通码? Y触发标志位flag=1? N N打开键盘中断和定时器中断 Y屏蔽定时器中断显示buffer中的字符串结束第一次键盘中断开中断flag=1? Y N中断结束开中断中断返回图1 程序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初值为1 mess db 0ah,0dh,Bell!,0ah,0dh,$;定义2个字符串 buffer db 0ah,0dh,Keyboard Interrupt!,0ah,0dh,$data ends;数据段定义结束stack segment 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,data mov ds,ax mov al,1ch ;取类型号为1CH的原中断向量 mov ah,35h;取中断向量的功能调用 int 21h;段址放入ES,偏址放入BX mov keep_ip08,es ;保存旧向量,存原中断向量段址 mov keep_cs08,bx;存原中断向量偏移量 push ds ;保存DS lea dx,timer ;子程序入口地址的偏移量(自编中断例行程序偏移地址)送DX mov ax,seg timer;子程序入口地址的段基 mov ds,ax;中断向量送 DS,自编中断例行程序段地址放入DS mov al,1ch;设置新中断向量1c(定时器中断),中断类型放入AL mov ah,25h;设置中断向量的功能调用 int 21h;设置新的中断向量,改变中断向量 pop ds ;恢复DS mov al,09h ;取中断向量09h mov ah,35h int 21h mov keep_ip09,es ;保存旧向量,存原中断向量段址 mov keep_cs09,bx;存原中断向量偏移量 push ds lea dx,kbdint ;新偏移量送DX,设置新中断向量09h(键盘中断) mov ax,seg kbdint mov ds,ax;新段址送DS,中断向量送 DS mov al,09h;写入新的中断向量 mov ah,25h int 21h pop ds in al,21h ;设置中断屏蔽寄存器,重新增设键盘中断和定时器中断 and al,0fch ;键盘和定时器址直由第0和1位 out 21h,al sti ;开中断,设置中断允许位(IF=1),允许CPU响应外设中断请求 mov di,20000;其实就是一个延时dly: mov si,30000;延时dly1: dec si;以下是一个双循环,就是控制程序时间 jnz dly1 dec di;可以调整si,di的数值,如果大,就是显示时间长 jnz dly ;主程序工作(期间每秒产生中断18.2次) cli ;清除中断允许位(IF=0),禁止CPU响应任何外设中断 jmp start push ds;保存DS mov dx,keep_ip08 ;恢复中断向量1ch mov ax,keep_cs08 mov ds,ax;自编中断例行程序段地址放入DS mov al,1ch;中断类型 mov ah,25h;设置中断向量 int 21h;DOS调用 pop ds;恢复DS push ds;保存DS mov dx,keep_ip09 ;恢复中断向量09h(键盘中断),取出保存的偏移地址 mov ax,keep_cs09;取出保存的段地址 mov ds,ax mov al,09h;中断类型 mov ah,25h;设置中断向量 int 21h;DOS调用 pop ds;恢复DS mov ah,4ch;结束程序 int 21hmain endp;-timer proc near push ds push ax push cx push dx;保存所有已修改的寄存器 mov ax,data mov ds,ax;数据段段始址送DS dec count;给count减1,就是变成0 jnz exit;不等于0退出,其实等于,所以输出 sti;开中断,允许更高级中断 mov dl,07h;响铃 mov ah,02h int 21h jmp $+2;两个字节,就是下面的命令,起到延时作用 lea dx,mess;输出提示字符串Bell! mov ah,09h int 21h mov count,91 ;count*1秒/18.2=5秒exit: cli;关中断 pop dx pop ax pop cx pop ds;恢复寄存器 iret;中断返回timer endp;-kbdint proc near;键盘中断处理程序 push ax;保存所有已修改的寄存器 in al,60h ;读键盘,从PA(60H)口读扫描码 push ax ;保存扫描码 in al,61h;读PB(61H)口信息 or al,80h out 61h,al ;置键盘应答位 in al,61h and al,7fh out 61h,al ;复位键盘应答位 pop ax test al,80h ;是通码? jnz inkret ;不是,中断返回 xor flag,1 ;是通码,则触发标志位 cmp flag,1 ;第一次按键? je process1 ;是,则挂起主程序和响铃process2: ;是第二次按键,则恢复主程序及响铃 in al,21h and al,0fch ;打开键盘中断和定时器中断 out 21h,al jmp inkretprocess1: in al,21h ;屏蔽定时器中断 or al,01 out 21h,al call display_char ;显示字符 mov al,20h ;结束第一次键盘中断 out 20h,al sti ;允许再次中断,开中断again:cmp flag,1 ;等待第二次键盘中断 je againinkret:mov al,20h ;中断结束命令 out 20h,al;送中断命令寄存器 sti pop ax;恢复寄存器 iret;中断返回kbdint endp;-display_char proc near;定义显示字符子程序 push ax push dx push ds;保存所有已修改的寄存器 mov ax,data mov ds,ax;数据段段始址送DS lea dx,buffer;显示buffer缓冲区中的字符串 mov ah,09h int 21h pop ds pop dx pop ax;保存所有已修改的寄存器 ret;返回DOSdisplay_char endp;-code ends;代码段定义结束 end start;整个程序到此结束五、运行结果1、在编辑源程序之后,用汇编程序MSAM.EXE进行汇编(格式为masm inter;),然后用链接程序LINK.EXE进行链接(格式为link inter;),最后运行程序(格式为inter)。2、运行结果说明:存储器中有一个地址为buffer的缓冲区,存放着一串ASCII码字符“Keyboard Interrupt!”。当运行inter.exe时,在主程序运行期间,每5秒钟响铃一次,且显示字符串“Bell!”;当键盘上的某个键被按下时,主程序和响铃都被挂起,显示器显示buffer缓冲区中的字符串,然后等待下一次按键引起的键盘中断;当键盘中断发生后,恢复主程序和响铃.这一过程可以重复任意次。六、遇到的问题及解决的方法1、由于以前没有学过有关中断服务程序的设计,所以开始时觉得无从下手,不知该怎么写程序,后来认真将书上的内容看了一遍,又看了一些例题,才着手写程序,在写的过程,还是边看书,边写程序,最后才将程序完成。2、开始没有注意区别两次按键的不同,后来知道:按下键和放开键都能引起键盘中断,但在处理键盘中断时,对按键所产生的代码不必解释处理,只需根据读取的扫描码的最高位确定是按键中断还是释放键中断。如果是释放键引起的中断,则无须做任何工作,直接从中断处理程序中退出。如果是按下键引起的中断,则要区别是第一次按键还是第二次按键,以便作出不同的处理,为此可

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论