Trap和Interrupt之间有什么区别?

218

“陷阱”和“中断”有什么区别?

如果不同系统的术语不同,那在x86上它们的含义是什么?

10个回答

265

陷阱是用户进程中的异常。它由除以零或无效内存访问引起。这也是调用内核例程(系统调用)的通常方式,因为它们以比用户代码更高的优先级运行。处理是同步的(因此用户代码被暂停,并在之后继续)。从某种意义上说,它们是“活动的” - 大多数情况下,代码期望发生陷阱并依赖于这个事实。

中断是由硬件(如硬盘、图形卡、I/O端口等设备)生成的东西。这些是异步的(即它们不会在用户代码的可预测位置发生)或“被动”的,因为中断处理程序必须等待它们最终发生。

您还可以将陷阱视为CPU内部中断的一种,因为陷阱处理程序的处理程序看起来像中断处理程序(寄存器和堆栈指针被保存,有上下文切换,在某些情况下可以恢复执行)。


8
有趣的是,http://lxr.free-electrons.com/source/arch/x86/kernel/traps.c?v=2.6.29#L965 中除以零错误被初始化为硬件中断。为什么会这样? - Alex Kreimer
12
这实际上是CPU在ALU发现问题时发送的中断,就像分段错误一样。但并非所有数学错误都会导致中断(例如溢出不会)。 - Aaron Digulla
6
明白了。但是,有点令人困惑的是,为什么在早期的Linux内核中它被初始化为一个软件陷阱:set_trap_gate(0,&divide_error)? - Alex Kreimer
15
你说的“有点混乱”,其实应该是“非常混乱” :-) 问题在于,除以零是一种硬件中断(IRQ /向量0),但内核开发人员有多种处理方式。因此,对于用户进程来说,它是一个陷阱,但从 CPU 方面来看,它是一个中断。谁是正确的?都不是?还是两者都是? - Aaron Digulla
5
当然,这仅适用于x86 CPU。其他CPU的工作方式不同。 - Aaron Digulla
显示剩余8条评论

163

陷阱中断密切相关。陷阱是一种异常,而异常类似于中断。

Intel x86定义了两个重叠的类别,向量事件(中断 vs 异常),以及异常类别(故障 vs 陷阱 vs 中止)。

本文中所有引用都来自于2016年4月版的Intel软件开发者手册。对于(明确而复杂的)x86视角,我建议阅读SDM关于中断和异常处理的章节。

向量事件

向量事件(中断异常)会导致处理器跳转到一个中断处理程序,同时保存处理器的大部分状态(足以在稍后从该点继续执行)。

异常和中断都有一个ID,称为向量,它确定处理器跳转到哪个中断处理程序。中断处理程序在中断描述符表中描述。

中断

中断在程序执行期间随机发生,响应硬件信号。系统硬件使用中断处理器外部事件,例如请求服务外围设备。软件也可以通过执行INT n指令生成中断。
异常是指当处理器执行指令时检测到错误条件(例如除以零)时发生的情况。处理器检测到各种错误条件,包括保护违规、页面故障和内部机器故障。
异常根据报告方式以及引起异常的指令是否可以重新启动而不会丢失程序或任务连续性,分为故障、陷阱或中止。
总结:陷阱增加指令指针,故障不会增加,而中止则“爆炸”。
陷阱

陷阱(trap)是在执行陷阱指令后立即报告的异常。陷阱允许程序或任务继续执行,而不会丢失程序连续性。陷阱处理程序的返回地址指向陷阱指令后要执行的指令。

故障(Fault)

故障(fault)是一种通常可以纠正的异常,并且一旦被纠正,程序可以重新启动,而不会丢失连续性。当报告故障时,处理器将机器状态恢复到故障指令开始执行之前的状态。故障处理程序的返回地址(CS和EIP寄存器的保存内容)指向故障指令,而不是指向故障指令后的指令。

例如:页面故障通常是可恢复的。应用程序的某个地址空间可能已经从RAM交换到磁盘上。当应用程序尝试访问已交换出的内存时,它会触发页面故障。内核可以将该内存从磁盘拷贝到RAM,并将控制权交还给应用程序。应用程序将从故障指令处继续执行(访问已交换出的内存的故障指令),但这次内存访问应该不会出现故障。

一个非法指令错误处理程序,如果要模拟浮点数或其他缺失的指令,需要在确定故障指令是否可以处理后,手动增加返回地址,以获得所需的陷阱类行为。x86 #UD 是一种"错误"而不是"陷阱"。(处理程序需要一个指向故障指令的指针来确定它是哪个指令。)

异常

异常是一种不总是报告导致异常的指令位置,并且不允许重新启动引发异常的程序或任务的例外情况。异常用于报告严重错误,例如硬件错误和系统表中不一致或非法值。

边缘情况

软件调用的中断(由INT指令触发)的行为方式类似于陷阱。在处理器保存状态并跳转到中断处理程序之前,指令完成执行。


8
这个答案太棒了,我确信“新用户的晚回答”审查队列是在考验我是否认真注意。 - Noumenon
2
谢谢!这对我来说意义重大 :) - ruthafjord
2
浏览了PPC架构书,看起来他们的定义在很大程度上是重叠的。他们为边缘情况命名,并将异常处理视为中断的子类型,而不是独立的一类。 - ruthafjord
3
我认为这个答案是最好的描述。它讨论了两者之间可能存在的模糊界限,并提到页面错误会导致CPU重新尝试指令,而陷阱跳过指令并继续执行。 - in70x
2
Alpha Architecture Reference Manual中,他们写道:“有三种类型的异常:1.故障是指在指令执行期间发生的异常情况...使得消除故障条件并随后重新执行指令将给出正确的结果。...”2.算术陷阱[没有重新执行陷阱指令]。3.同步陷阱(分为数据对齐陷阱和其他陷阱,例如BreakPoint Trap、Illegal Instruction Trap、Generate Software Trap、Change Mode To Kernel Trap等)。 - imz -- Ivan Zakharyaschev
显示剩余3条评论

12

通常来说,像是异常、故障、中止、陷阱中断这些术语都指的是同一件事情,并统称为“中断”。

那么,陷阱和中断之间的区别是什么呢?

陷阱:是由程序员发起的并且预期的控制传递到一个特殊的处理程序例程的过程。(例如:80x86 INT指令就是一个很好的例子)

中断(硬件):是基于CPU外部硬件事件的程序控制中断(例如:按下键盘上的某个键或定时器芯片的超时事件)。


好的定义。来源是什么? - alelom

12

陷阱是一种特殊的中断,通常被称为软件中断中断是一个更普遍的术语,涵盖了硬件中断(来自硬件设备的中断)和软件中断(来自软件的中断,如陷阱)。


4
有些作者(如Tanenbaum)将“硬件陷阱”称为“hardware traps”,这更加混淆了问题。如果我们可以有硬件陷阱和软件中断,那么很明显定义相当模糊,可以两者皆可,而且总是需要使用硬件或软件这个词。 - The111

5

代码程序会调用陷阱,例如调用操作系统例程(通常是同步的)。

事件会调用中断(通常是硬件事件,如网络卡接收到数据或CPU定时器),正如其名称所示,中断了正常的控制流,因为CPU必须切换到驱动程序例程来处理该事件。


4

我认为陷阱是由当前指令的执行引起的,因此它们被称为同步事件。而中断是由处理器中正在运行的独立指令引起的,与外部事件有关,因此被称为异步事件。


4

中断是硬件中断,而陷阱是软件调用的中断。硬件中断的发生通常会禁用其他硬件中断,但这对于陷阱来说并不成立。如果您需要在服务陷阱之前禁止硬件中断,则需要显式清除中断标志。通常计算机上的中断标志影响(硬件)中断而不是陷阱。这意味着清除此标志将无法防止陷阱。与陷阱不同,中断应该保留 CPU 的先前状态。


4

陷阱是一种软件中断。如果您编写一个声明了被零除的变量的程序,则会将其视为陷阱。每当您运行此程序时,它都会在同一时间抛出相同的错误。系统调用是陷阱的特殊版本,在其中程序请求操作系统提供其所需的服务。 在中断(硬件中断的通用术语)的情况下,例如i/o错误,cpu在随机时间被中断,这当然不是我们程序员的问题。这是硬件引起的。


1
你能解释一下系统调用如何成为陷阱吗? - Radha Gogia
1
系统调用需要从用户模式切换到内核模式。包装系统调用的库调用会触发信号,以便进行此切换,并且它可能会查看寄存器,以确定用户空间将传递哪些数据给系统调用。 - GL2014

3

中断是系统内部由硬件产生的流程变化。中断处理程序被唤醒来处理中断的原因;然后将控制返回到中断上下文和指令。陷阱是软件生成的中断。可以使用中断来表示I/O完成,以避免需要设备轮询。可以使用陷阱来调用操作系统例程或捕获算术错误。


1
一个陷阱可以被认为是由程序员发起的控制传递。术语Trap和Exception(它是自动发生的软件中断)可互换使用。但有些人可能会认为陷阱只是一个特殊的子例程调用,因此它们属于软件调用的中断类别。例如,在80×86机器中,程序员可以使用int指令来发起陷阱。因为陷阱总是无条件的,控制流将始终转移到与陷阱相关联的子例程。调用处理陷阱的精确指令很容易识别,因为使用明确的指令来指定陷阱。陷阱与中断

术语可能会有所不同。例如,gcc -ftrapping-math 告诉它(尝试但未成功地)进行优化,以使结果与 C 抽象机器匹配,即使像除以 0 这样的事情也会运行信号处理程序。(即在 FP 异常上陷阱)。但术语取决于供应商的文档。然而,在 Intel 上,int 0x?? 不是唯一的陷阱方式。TRAP、软件中断和硬件中断之间的区别? 表示像 div 除以零(#DE 异常)这样的事情也是一个陷阱。这个问题的被接受的答案也是如此。 - Peter Cordes
你在英特尔手册中有关于陷阱始终是“故意”的声明来源吗?即来自始终会触发陷阱的指令而不是数据相关的指令?或者我猜你并没有做出强烈的声明,只是说“有人可能会争辩”。顺便说一句,我不确定安迪·格卢(Intel P6的架构师之一)在他的回答中使用了英特尔特定的术语还是更通用的术语,他同时使用“trap”和“exception”这两个术语具有特定的含义。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接