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

What's the difference between Software-Generated Interrupt and Software-Generated Exception?

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

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

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

The INT n instruction permits interrupts to be generated from within software by supplying an interrupt vector number as an operand. For example, the INT 35 instruction forces an implicit call to the interrupt handler for interrupt 35. Any of the interrupt vectors from 0 to 255 can be used as a parameter in this instruction. If the processor’s predefined NMI vector is used, however, the response of the processor will not be the same as it would be from an NMI interrupt generated in the normal manner. If vector number 2 (the NMI vector) is used in this instruction, the NMI interrupt handler is called, but the processor’s NMI-handling hardware is not activated. Interrupts generated in software with the INT n instruction cannot be masked by the IF flag in the EFLAGS register.

对于软件生成的异常,它表示:

The INTO, INT 3, and BOUND instructions permit exceptions to be generated in software. These instructions allow checks for exception conditions to be performed at points in the instruction stream. For example, INT 3 causes a breakpoint exception to be generated. The INT n instruction can be used to emulate exceptions in software; but there is a limitation. If INT n provides a vector for one of the architecturally-defined exceptions, the processor generates an interrupt to the correct vector (to access the exception handler) but does not push an error code on the stack. This is true even if the associated hardware-generated exception normally produces an error code. The exception handler will still attempt to pop an error code from the stack while handling the exception. Because no error code was pushed, the handler will pop off and discard the EIP instead (in place of the missing error code). This sends the return to the wrong location.

那么,有什么区别呢?似乎都利用了 int n 指令。如何在一段汇编代码中判断它产生的是异常还是中断?

在 x86 体系结构中,异常作为中断处理,名义上由中断处理程序处理。
所以中断和异常是重叠的术语,后者是前者的一种。

中断编号 0 到 31 保留用于 CPU 异常,例如中断编号 0 是#DE(除法错误),中断编号 13 是#GP(一般保护)。

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

首先它会在需要时推送错误代码,一些异常(如#PF 和#GP)会推送,一些异常(如#DE)不会推送。
Intel manual 3 的第 6.15 节列出了所有异常及其最终错误代码。

其次,它“调用”适当的中断处理程序,这类似于远程调用,但 EFLAGS 压入堆栈。

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

当您在代码中看到 int n 时,绝不会 出现异常。它是一个中断,最终用于将控制流引导到特定的 OS 异常处理程序。


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