问题描述
具有这样的程序集用户空间程序:
_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会将其他信息写入堆栈。对于其他异常类型(例如“页面错误”),有包含附加信息的特殊寄存器。