cpu如何通知内核有关硬件异常的信息?

问题描述

具有这样的程序集用户空间程序:

_start:
data: db"DATA..........."
    mov eax,5

导致cpu执行数据,这将导致硬件异常,该异常应被linux内核捕获,这将导致分段错误并终止程序。我的问题是cpu如何告知内核有关该异常的信息,以及是否有一些细节(例如被零除或数据执行异常),以及当此类异常发生以处理该异常(诸如kernal之类的东西)时,它如何知道下一步执行什么指令?我猜是硬件异常处理程序)

解决方法

执行任意数据通常会导致未定义的指令异常#UD。 (但是它也可能首先导致页面错误,GP错误或其他一些异常。并且有可能毫无错误地进入循环。)

当CPU检测到故障时,它将转换为内核模式,并从IDT加载与故障号相对应的描述符(#UD的描述符6)。它将当前的SS,RSP,标志,CS和RIP推入内核堆栈。它开始在IDT描述符中的地址处执行内核代码。内核通过开始执行的处理程序的地址可以知道它是#UD而不是其他一些异常。

,

我的问题是CPU如何将异常告知内核...

...以及如何知道要执行的下一条指令...

在x86 CPU上,异常是中断(就像硬件中断或int指令调用的中断一样):

当发生某种异常时,CPU会将指令的地址和一些其他信息压入内核堆栈,并跳转到中断向量表中指定的地址。

内核可以读取压入堆栈的地址,以获取有关引起异常的指令的信息。

...还有一些详细信息...

不同类型的异常调用不同的中断向量:

“除以零”将导致跳转到中断向量表中第一个条目中指定的地址; “页面错误”将导致跳转到该表的第15个条目中指定的地址。

对于不同种类的异常,操作系统具有不同的“异常处理程序”(在异常情况下由硬件调用的汇编程序)。这些处理程序的地址存储在中断向量表中。 CPU将从该表中读取处理程序的地址。

对于某些异常类型(例如“常规保护错误”),CPU会将其他信息写入堆栈。对于其他异常类型(例如“页面错误”),有包含附加信息的特殊寄存器。