Intel官方白皮书Volume3的6.5节
异常分为3种,
错误(fault)、陷阱(trap)、终止(abort)
- 错误(fault):错误是一种可以被修复的异常,只要错误被修正,处理器就可以将进程或任务的运行环境恢复到这条语句的执行地址,继续执行
- 陷阱(trap):一条指令产生了异常,其状态同样可以恢复,但是执行异常处理程序之后恢复的位置是异常指令的下一条指令
- 终止(abort):十分严重的错误,异常原因无迹可循,会终止程序或任务的执行,无法恢复
终止异常发生后,程序不会再继续执行(或者说现场不可恢复),而错误、陷阱两种异常可以恢复程序的现场,但是错误会重新执行触发异常的指令,而陷阱会跳到异常指令的下一条指令
对于错误和陷阱,因为可以恢复现场,那么从当前指令跳转到中断处理程序这个过程中,需要保存当前的程序状态(将EFLAGES、CS、EIP,错误代码(ErrorCode)入栈),在这之中,可能会有一种情况,当中断处理程序的特权级比当前程序的特权级要大的时候,还需要切换栈帧,则在保存之前的那些程序状态之前,还需要将当前程序的堆栈信息保存到中断处理程序的堆栈中去
- 异常程序和中断处理程序的特权级相同
- 异常程序的特权级小于中断处理程序的特权级
归纳起来中断处理程序的调用过程可以这样理解
- 指令执行发生异常
根据异常捕获的中断向量号在中断描述符表IDT中查找相关记录,得到
段选择子(Selecor)
和段内偏移地址(Offset)
,段选择子是一个索引,用于在GDT(全局描述符表)
或LDT(局部描述符表)
获得段的基址Base
,根据Base+Offset
得到程序地址,利用call跳转到中断处理程序中去
- 执行中断处理程序
跳转到中断处理程序之后,检查中断处理程序的特权级与当前特权级进行比较,如果中断处理特权级大于当前特权级,则需要切换堆栈,并且在保存
EFLAGS、CS、EIP、ErrorCode
之后还要保存当前程序的堆栈信息(SS+ESP)
,然后开始执行中断处理程序,执行完毕之后,恢复现场