软件生成的中断和软件生成的异常有啥区别?
Posted
技术标签:
【中文标题】软件生成的中断和软件生成的异常有啥区别?【英文标题】:What's the difference between Software-Generated Interrupt and Software-Generated Exception?软件生成的中断和软件生成的异常有什么区别? 【发布时间】:2017-03-22 22:52:24 【问题描述】:我正在阅读英特尔手册 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
指令。如何判断一段汇编代码是产生异常还是中断?
【问题讨论】:
这是一个晦涩的细节,只对编写保护模式操作系统的人很重要。如前所述,他最好确保 n 【参考方案1】:在 x86 架构中,异常作为中断处理,名义上是使用中断处理程序。 所以中断和异常是重叠的术语,后者是前者的一种。
从 0 到 31 的中断号是为 CPU 异常保留的,例如中断号 0 是#DE(除法错误),中断号 13 是#GP(一般保护)。
当 CPU 检测到应该引发异常的条件(例如访问不存在的页面)时,它会执行一系列任务。
首先,如果需要,它会推送一个错误代码,一些异常(如#PF 和#GP)会,一些(如#DE)不会。Intel manual 3 的第 6.15 节列出了所有异常及其最终错误代码。
其次,它“调用”适当的中断处理程序,类似于远调用,但 EFLAGS 被压入堆栈。
int n
只执行第二步,它调用中断但不推送任何错误代码,因为首先硬件中没有错误条件(并且因为int n
在 错误代码)。
因此它可以用于模拟异常,软件最终必须推送适当的错误代码。
当您在代码中看到int n
时,它从不 异常。它是一个中断,最终用于将控制流引导到特定的操作系统异常处理程序中。
琐事:int3
(没有空格)是特殊的,因为它被编码为CC
,它只有一个字节(正常的int n
是CD imm8
)。这对于调试很有用,因为调试器可以将它放在代码段中的任何位置。into
仅在 OF = 1 时生成 #OF 异常。
【讨论】:
非常感谢。所以我现在的理解是,异常可能有错误代码。中断不会。异常可以分类为Fault
、Trap
、Abort
。我检查了向量 0~31,它们都属于这 3 种类型之一,但向量 3,即 NMI,是一个中断。异常来自处理器内部,而中断来自处理器外部。
顺便说一句,imm8
是什么意思?为什么单字节编码使得int 3
可以放在代码段中的任何位置?
@smwikipedia imm8` 表示 *8 位立即数,例如,CD 21
是 int 21h
,CD 67
是 int 67h
。对不起,没有澄清这一点。关于int 3
,我可以引用 Intel 来回答:“这种单字节形式很有价值,因为它可以用来用断点替换任何指令的第一个字节,包括其他单字节指令,无需覆盖其他代码”。这可能在我的回答中表达得很糟糕。
@smwikipedia 是的,但是由于 x86 作为可变长度指令,CPU 会逐步解码它们,只要字节序列是有效指令,CPU 就会执行它(这就是为什么没有指令可以作为前缀另一个)。由于int 3
是一个字节长,即最小指令长度,CPU 肯定会将以CC
开头的字节流解码为int 3
。这会生成#DB 异常,并且调试器会在内存中恢复正确的指令。
@smwikipedia x86 tag info 有很多链接。不幸的是,我无法判断哪些与您的问题相关。当然,英特尔手册的副本是强制性的,以及一些 Google 技能:)以上是关于软件生成的中断和软件生成的异常有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Linux中断 异常 系统调用 中断上半部 中断下半部 这些有啥区别和联系