首页 文章

软件生成的中断和软件生成的异常之间有什么区别?

提问于
浏览
1

我正在阅读英特尔手册3A第6章中断和异常处理 .

中断和异常分别有3个来源 .

对于软件生成的中断,它说:

INT n指令允许通过提供中断向量编号作为操作数从软件内生成中断 . 例如,INT 35指令强制对中断35的中断处理程序进行隐式调用 . 任何0到255的中断向量都可以用作该指令中的参数 . 但是,如果使用处理器的预定义NMI向量,则处理器的响应将与以正常方式生成的NMI中断的响应不同 . 如果在该指令中使用向量编号2(NMI向量),则调用NMI中断处理程序,但不激活处理器的NMI处理硬件 . 使用INT n指令在软件中产生的中断不能被EFLAGS寄存器中的IF标志屏蔽 .

对于软件生成的例外,它说:

INTO,INT 3和BOUND指令允许在软件中生成异常 . 这些指令允许在指令流中的点处执行异常条件的检查 . 例如,INT 3会生成断点异常 . INT n指令可用于模拟软件中的异常;但是有一个限制 . 如果INT n为架构定义的异常之一提供向量,则处理器会生成正确向量的中断(以访问异常处理程序),但不会在堆栈上推送错误代码 . 即使相关的硬件生成的异常通常会产生错误代码,也是如此 . 在处理异常时,异常处理程序仍将尝试从堆栈中弹出错误代码 . 因为没有推送错误代码,处理程序将弹出并丢弃EIP(代替丢失的错误代码) . 这会将返回发送到错误的位置 .

那么,有什么区别?似乎都利用 int n 指令 . 如何判断它是否在汇编代码中生成异常或中断?

1 回答

  • 2

    在x86架构中,异常作为中断处理,名义上带有中断处理程序 .
    所以中断和异常是重叠的术语,后者是前者的一种 .

    从0到31的中断号保留用于CPU异常,例如,中断号0是#DE(分频错误),中断号13是#GP(通用保护) .

    当CPU检测到应该引发异常的情况时(如访问非当前页面),它会执行一系列任务 .

    首先,如果需要,它会推送一个错误代码,一些例外(如#PF和#GP),一些(如#DE)不这样做 .
    Intel manual 2的第6.15节列出了所有异常及其最终错误代码 .

    其次它"call"适当的中断处理程序,就像一个远程调用,但EFLAGS被推入堆栈 .

    int n 仅执行第二步,它调用中断但不会推送任何错误代码,因为首先硬件中没有错误条件(并且因为错误代码的概念之前存在 int n ) .
    因此它可以用来模拟异常,软件最终必须推送适当的错误代码 .

    当你在代码中看到 int n 时,它永远不会是例外 . 它是一个中断,最终用于将控制流引导到特定的OS异常处理程序中 .


    琐事: int 3 是特殊的,因为它被编码为 CC ,它只有一个字节(正常 int nCD imm8 ) . 这对于调试很有用,因为调试器可以将它放在代码段中的任何位置 .
    into 仅在OF = 1时生成#OF异常 .

相关问题