cpu 如何向内核发出硬件异常信号?

how cpu signal kernal about a hardware exception?

有这样的程序集用户-space:

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

导致 CPU 执行数据,这将导致硬件异常,该异常应该被 linux 内核捕获,这将导致分段错误并终止程序。我的问题是 CPU 如何告诉内核异常以及是否有一些细节(例如被零除或数据执行异常)以及它如何知道在处理异常时发生这样的异常时要执行的下一条指令(我猜类似于内核硬件异常处理程序)

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

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

My question is how CPU tell kernel about the exception ...

... and how it knows what next instruction to execute ...

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

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

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

... and if there is some details ...

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

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

的第 15 个条目中指定的地址

OS针对不同类型的异常有不同的“异常处理程序”(硬件在异常情况下调用的汇编程序)。这些处理程序的地址存储在中断向量 table 中。 CPU 将从 table 中读取处理程序的地址。

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