1.错误
异常被处理后,再次执行触发异常指令
2.陷阱
异常被处理后,执行触发异步指令之后指令
3.终止
异常被处理后,终止运行
向量号0~20目前已经固定分配给异常。向量号2除外。
向量号21~31目前属于Intel保留区间。无法使用。
向量号32~255属于用户自定义区间,可供处理外部中断。
向量号 | 助记符 | 描述 | 异常类型 | 错误码 | 触发源 |
0 | #DE | 除法错误 | 错误 | No | DIV或IDIV指令 |
1 | #DB | 调试异常 | 错误/陷阱 | No | 仅供Intel处理器使用 |
3 | #BP | 断点异常 | 陷阱 | No | INT 3指令 |
4 | #OF | 溢出异常 | 陷阱 | No | INTO指令 |
5 | #BR | 越界异常 | 错误 | No | BOUND指令 |
6 | #UD | 无效/未定义的机器码 | 错误 | No | UD2指令或保留的机器码 |
7 | #NM | 设备异常(FPU不存在) | 错误 | No | 浮点指令WAIT/FWAIT指令 |
8 | #DF | 双重错误 | 终止 | Yes(Zero) | 任何异常,NMI中断或INTR中断 |
9 | 协处理器段越界(保留) | 错误 | No | 浮点指令 | |
10 | #TS | 无效的TSS段 | 错误 | Yes | 访问TSS段或任务切换 |
11 | #NP | 段不存在 | 错误 | Yes | 加载段寄存器或访问系统段 |
12 | #SS | SS段错误 | 错误 | Yes | 栈操作或加载栈段寄存器SS |
13 | #GP | 通用保护性异常 | 错误 | Yes | 任何内存引用和保护检测 |
14 | #PF | 页错误 | 错误 | Yes | 任何内存引用 |
16 | #MF | x87 FPU错误(计算错误) | 错误 | No | x87 FPU浮点指令或WAIT/FWAIT指令 |
17 | #AC | 对齐检测 | 错误 | Yes(Zero) | 引用内存中的任何数据 |
18 | #MC | 机器检测 | 终止 | No | 如有错误码,其与CPU类型有关 |
19 | #XM | SIMD浮点异常 | 错误 | No | SSE/SSE2/SSE3浮点指令 |
20 | #VE | 虚拟化异常 | 错误 | No | 违反EPT |
1.处理器捕获到异常时,根据异常向量号从IDT索引出对应的门描述符
2.由门描述符定位到处理程序的位置。
如果向量号索引到一个中断门或陷阱门,处理器会像执行CALL访问调用门一般,去执行异常处理程序。
3.在确定了处理程序的段选择子,段内偏移后。
3.1.如果异常处理程序的特权级更高,则先完成栈空间切换,再执行流程跳转。
3.1.1.处理器从TR找到TSS,从TSS取出对应特权级的栈段选择子和栈指针。用取出信息设置SS,ESP。
3.1.2.将之前的SS,ESP寄存器值压入栈
3.1.3.将EFLAGS,CS,EIP寄存器值压入栈
3.1.4.如异常向量号会产生错误码,
3.1.4.1.错误码压入栈。
3.1.5.如向量号索引到的是中断门
3.1.5.1.将EFLAGS中IF标志位复位。IF被复位后,可以起到禁止外部可屏蔽中断的效果。
3.2.如果异常处理程序特权级与CS中特权级一致
3.2.1.将EFLAGS,CS,EIP寄存器值入栈
3.2.2.如异常向量号会产生错误码
3.2.2.1.错误码压入栈
3.2.3.如向量号索引到的是中断门
3.2.3.1.将EFLAGS中IF标志位复位。IF被复位后,可以起到禁止外部可屏蔽中断的效果。
1.执行IRET
IRET详细解析:
1.异常进入时,若发生了特权级切换(由此引发栈切换)
1.1.出栈得到EIP,CS,EFLAGS,SS,ESP
1.2.设置出栈的EFLAGS到EFLAGS
1.3.设置出栈的SS,ESP到SS,ESP
1.4.设置出栈的EIP,CS到EIP,CS
1.4执行后,就完成了执行流程的跳转返回。
2.异常进入时,若未发生特权级切换
2.1.出栈得到EIP,CS,EFLAGS
2.2.设置出栈的EFLAGS到EFLAGS
2.3.设置出栈的EIP,CS到EIP,CS
2.3执行后,就完成了执行流程的跳转返回。
1.2.1.异常向量号0处理实践
1.2.2.异常向量号14处理实践