异常就是CPU内部出现的中断,也就是说,在CPU执行特定指令时出现的非法情况。非屏蔽中断就是计算机内部硬件出错时引起的异常情况。从上图可以看出,二者与外部I/O接口没有任何关系。Intel把非屏蔽中断作为异常的一种来处理,因此,后面所提到的异常也包括了非屏蔽中断。在CPU执行一个异常处理程序时,就不再为其他异常或可屏蔽中断请求服务,也就是说,当某个异常被响应后,CPU清除eflag的中IF位,禁止任何可屏蔽中断。但如果又有异常产生,则由CPU锁存(CPU具有缓冲异常的能力),待这个异常处理完后,才响应被锁存的异常。我们这里讨论的异常中断向量在0~31之间,不包括系统调用(中断向量为0x80)。
Intel x86处理器发布了大约20种异常(具体数字与处理器模式有关)。Linux内核必须为每种异常提供一个专门的异常处理程序。这里特别说明的是,在某些异常处理程序开始执行之前,CPU控制单元会产生一个硬件错误码,内核先把这个错误码压入内核栈中
在表3.1中给出了Pentium模型中异常的向量、名字、类型及简单描述。更多的信息可以在Intel的技术文挡中找到。
表3.1 异常的简单描述
向量 | 异常名 | 类别 | 描述 |
0 | 除法出错 | 故障 | 被0除 |
1 | 调试 | 故障/陷阱 | 当对一个程序进行逐步调试时 |
2
| 非屏蔽中断 (NMI) | /
| 为不可屏蔽中断保留
|
3 | 断点 | 陷阱 | 由int3(断点指令)指令引起 |
4
| 溢出
| 陷阱
| 当into(check for overflow)指令被执行
|
5 | 边界检查 | 故障 | 当bound指令被执行 |
6 | 非法操作码 | 故障 | 当CPU检查到一个无效的操作码 |
7
| 设备不可用
| 故障
| 随着设置cr0的TS标志, ESCAPE或MMX指令被 执行 |
8 | 双重故障 | 故障 | 处理器不能串行处理异常而引起的 |
9
| 协处理器段越界
| 故障
| 因外部的数学协处理器引起的问题(仅用在 80386) |
10 | 无效TSS | 故障 | 要切换到的进程具有无效的TSS |
11 | 段不存在 | 故障 | 引用一个不存在的内存段 |
12 | 栈段异常 | 故障 | 试图超过栈段界限,或由ss标识的段不在内存 |
13 | 通用保护 | 故障 | 违反了Intelx86保护模式下的一个保护规则 |
14 | 页异常 | 故障 | 寻址的页不在内存,或违反了一种分页保护机制 |
15 | Intel 保留 | / | 保留 |
16 | 浮点出错 | 故障 | 浮点单元用信号通知一个错误情形,如溢出。 |
17 | 对齐检查 | 故障
| 操作数的地址没有被正确地排列
|
18~31由Intel保留,为将来的扩充用