当前位置: 代码迷 >> 汇编语言 >> 关于intel中断,该怎么处理
  详细解决方案

关于intel中断,该怎么处理

热度:4922   发布时间:2013-02-26 00:00:00.0
关于intel中断
我的汇编代码在保护模式下,实现了一个键盘中断响应函数。
这个函数很简单,就是在屏幕上显示一个字符串,然后返回。我预期的效果是每按一次键,屏幕上就会在上一个字符串的下一行显示相同的一个字符串。
但是程序运行起来之后,只能响应一次键盘输入(只显示出一个字符串),之后的键盘输入都不能响应。这是为什么呢?

我的键盘中断响应函数是这样的:

;键盘中断处理(汇编文件)
extern key_interrupt
key_int:  
;key_int这个汇编函数调用C语言文件中的key_interrupt函数
  call key_interrupt
  iretd

//下面是C语言文件中的函数
void key_interrupt()
{
  disp_str("Key Pressed\n");
}

;内核文件是这样的(有些代码省略了)
_start:
  .......
  call cstart;在这个函数里面初始化IDT
  ;加载idt
  lidt [idt_ptr]
  sti
  hlt

------解决方案--------------------------------------------------------
每次中断程序完成后需要发一个EOI信号给8259A中断控制器,以便继续接收下一个中断!

mov al, 020h ; 中断复位
out 020h, al

------解决方案--------------------------------------------------------
Assembly code
_@Int21:        call    _@Ksave        in      al, 021h                ; 将键盘中断屏蔽,在此过程中不再响应键盘中断        or      al, (1<<1)        out     021h, al        mov     al, 020h                ; 中断复位,其他中断可继续        out     020h, al        sti                             ; 置中断屏蔽位, 继续响应外部中断    ; //////////////////////////////////////////////    ; 中断处理过程        call    _@KeyInScan    ; //////////////////////////////////////////////        cli                             ; 清中断屏蔽位, 暂停响应外部中断        in      al, 021h                ; 将键盘中断打开        and     al, ~(1<<1)        out     021h, al        ret
------解决方案--------------------------------------------------------
注意!iret 返回在 _@Ksave 代码中,返回地址入栈了,这里ret返回时正好是 _@Ksave 中调用_@Int21下一句。iret返回时自动打开中断。
  相关解决方案