我正在阅读英特尔手册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
指令。如何判断它是否在汇编代码中生成异常或中断?
答案 0 :(得分:2)
在x86架构中,异常作为中断处理,名义上带有中断处理程序 因此,中断和异常是重叠的术语,后者是前者的一种。
从0到31的中断号保留用于CPU异常,例如,中断号0是#DE(分频错误),中断号13是#GP(通用保护)。
当CPU检测到应该引发异常的情况时(如访问非当前页面),它会执行一系列任务。
首先,如果需要,它会推送错误代码,有些例外(例如#PF和#GP)会执行,有些例外(例如#DE)不会这样做。
Intel manual 2的第6.15节列出了所有异常及其最终错误代码。
其次"打电话"适当的中断处理程序,就像远程调用,但在堆栈上推送 EFLAGS 。
int n
仅执行第二步,它会调用中断,但不会推送任何错误代码,因为硬件中没有错误条件(因为int n
是在错误代码的概念之前
因此,它可用于模拟异常,软件必须最终推送适当的错误代码。
当您在代码中看到int n
时,永远不会和异常。它是一个中断,最终用于将控制流引导到特定的OS异常处理程序中。
琐事:int 3
很特殊,因为它被编码为CC
,只有一个字节(普通int n
是CD imm8
)。这对于调试很有用,因为调试器可以将它放在代码段中的任何位置
如果 OF = 1 ,则into
仅生成#OF异常。