我正在阅读英特尔手册 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 会导致生成断点异常。情报局
n 指令可用于模拟软件中的异常;但那里
是一个限制。如果 INT n 为其中之一提供向量
架构定义的异常,处理器生成一个
中断到正确的向量(以访问异常处理程序)但是
不会将错误代码压入堆栈。即使
相关的硬件生成的异常通常会产生错误
代码。异常处理程序仍会尝试弹出错误代码
处理异常时从堆栈中取出。因为没有错误代码
按下后,处理程序将弹出并丢弃 EIP(就地
缺少的错误代码)。这会导致返回错误
地点。
那么,有什么区别呢?似乎两者都利用了int n
操作说明。如何判断一段汇编代码中是否产生异常或中断?
在 x86 架构中,异常被作为中断来处理,名义上是通过中断处理程序来处理的。
所以中断和异常是重叠的术语,后者是前者的一种。
中断号从0到31是为CPU异常保留的,例如中断号0是#DE(除法错误),中断号13是#GP(一般保护)。
当 CPU 检测到应引发异常的情况(例如访问不存在的页面)时,它会执行一系列任务。
首先,如果需要,它会推送错误代码,有些异常(如#PF 和#GP)会推送错误代码,有些(如#DE)则不会。
第 6.15 条英特尔手册3 https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html列出所有异常及其最终错误代码。
其次,它“调用”适当的中断处理程序,这类似于远调用,但具有EFLAGS压入堆栈。
int n
仅执行第二步,它调用中断但不推送任何错误代码,因为硬件中首先没有错误条件(并且因为int n
在这个概念之前就已经存在了错误代码).
所以它可以用来emulate异常情况下,软件最终必须推送适当的错误代码。
当你看到int n
在代码中,它是never一个例外。它是一个中断,最终用于将控制流引导到特定的操作系统异常处理程序。
Trivia: int3
(没有空格)很特殊,因为它被编码为CC
这只是一个字节(正常int n
is CD imm8
)。这对于调试很有用,因为调试器可以将其放置在代码段中的任何位置。
into
仅在以下情况下生成 #OF 异常:OF = 1.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)