计算机的中断类型有两种:硬中断与软中断。一般把计算机硬件设备对CPU产生的中断请求称为硬中断,而把计算机软件程序通过使用int n指令而对CPU产生的中断称为软件中断。而从CPU与中断发生的位置来区分也常常将硬中断称作外中断,因为它发生在CPU的外部。相反的,将CPU在执行程序过程中出现的中断称为内中断。
关于软中断的中断向量如下:
中断向量 |
异常 |
0x00 |
除零错 |
0x01 |
调试异常 |
0x02 |
不可屏蔽中断 |
0x03 |
断电 |
0x04 |
上溢出 |
0x05 |
边界检查 |
0x06 |
无效操作码 |
0x07 |
无协处理器 |
0x08 |
双重错误 |
0x09 |
协处理器段超限 |
0x0A |
无效的TSS |
0x0B |
段不存在 |
0x0C |
栈异常 |
0x0D |
一般保护错 |
0x0E |
页错误 |
0x0F |
保留 |
0x10 |
协处理器错 |
0x11-0x19 |
保留 |
0x1A-0xFF |
未用 |
外部中断主要是由两个8259A中断控制器(PIC和PIC2)来产生,每个8259A有8根中断信号线(IRQ0-IRQ7和IRQ8-IRQ15),两个级联在一起的8259A中断控制器可以挂接15个不同的外部设备,为这些外设提供中断控制处理,并可以向CPU发送中断信号。计算机在启动时BISO程序已经对8259A进行了相应的设置,其设置结果如下:
IRQ0-IRQ7被BISO程序所设置的中断向量为0x8-0x0f,IRQ8-IRQ15的中断向量为0x70-0x77。如下表:
IRQ |
中断向量 |
中断 |
IRQ0 |
0x08 |
时钟 |
IRQ1 |
0x09 |
键盘 |
IRQ2 |
0x0A |
PIC2 |
IRQ3 |
0x0B |
COM2 |
IRQ4 |
0x0C |
COM1 |
IRQ5 |
0x0D |
LPT2 |
IRQ6 |
0x0E |
软驱 |
IRQ7 |
0x0F |
LPT1 |
IRQ8 |
0x70 |
实时时钟 |
IRQ9 |
0x71 |
重定向IRQ2 |
IRQ10 |
0x72 |
保留 |
IRQ11 |
0x73 |
保留 |
IRQ12 |
0x74 |
PS/2鼠标 |
IRQ13 |
0x75 |
FPU异常 |
IRQ14 |
0x76 |
IDE0 |
IRQ15 |
0x77 |
IDE1 |
通过软中断向量表和硬中断向量表可以看到它们的中断向量有一部分是重叠的,也就是0x08-0x0f这部分。由于8259A是可编程的中断控制器,所以可以对其编程重新指定它的中断向量。我们打算让IRQ0-IRQ15的中断向量号为0x20-0x2f。8259A是通过向相应的端口写入特定的ICW来实现的,主8259A对应的端口地址为0x20和0x21,从8259A对应的端口地址是0xa0和0xa1。而ICW一共有4个,每一个都是具有特定格式的字节。下面看一下4个ICW的特定格式:
知道了可编程中断控制器8259A的控制方式就可以对其进行重新编程,使它的中断向量为0x20-0x2f与CPU异常中断向量分开,不再重叠:
//设置主8259A和从8259A outb_p(0x11, 0x20); outb_p(0x11, 0xa0); //设置IRQ0-IRQ7的中断向量为0x20-0x27 outb_p(0x20, 0x21); //设置IRQ8-IRQ15的中断向量为0x28-0x2f outb_p(0x28, 0xa1); //使从片PIC2连接到主片上 outb_p(0x04, 0x21); outb_p(0x02, 0xa1); //打开8086模式 outb_p(0x01, 0x21); outb_p(0x01, 0xa1);
设置完了8259A之后还要做一件事情,虽然我们对8259A重新编程并设置了其中断向量,但是系统内核程序并没有能够处理这些中断相应的程序。也就是说,当CPU接收了一个中断信号时,并不知道要执行什么样的程序来响应中断。所以我们要暂时将这些中断关闭,等到完成了中断处理程序之后再将这些中断逐个打开。将IRQ0-IRQ15的中断暂时关闭:
//关闭IRQ0-IRQ7的0x20-0x27中断 outb_p(0xff, 0x21); //关闭IRQ8-IRQ15的0x28-0x2f中断 outb_p(0xff, 0xa1);
Copyright © 2015-2023 问渠网 辽ICP备15013245号