我在这里所做的所有参考资料均来自AMD64架构程序员手册第2卷:系统编程 http://support.amd.com/us/Processor_TechDocs/24593_APM_v2.pdf,它还描述了传统保护模式(即 x86)行为。
第 240 页上的图 8-8 显示了相同特权级别中断后的堆栈布局(即进入 ISR 时的堆栈布局):
在第 8.2.14 节中,您可以看到#GP
提供错误代码,以下内容也很有趣:
程序重新启动。 #GP
是一个错误类型的异常。在大多数情况下,
保存的指令指针指向引起该指令的指令#GP
。请参阅第 230 页的“任务切换期间的异常”,了解在任务切换期间发生此异常时的后果的描述。
任务切换。
引用的部分提到了以下内容:
加载段时任务切换期间可能会发生异常
选择器。访问 TSS 时也可能发生页面错误。在这些
情况下,硬件任务切换机制完成加载新的任务
从 TSS 获取任务状态,然后触发相应的异常
机制。不执行其他检查。当这种情况发生时,保存的
指令指针指向新任务中的第一条指令。
因此,除非您使用硬件任务切换,否则保存的指令指针始终指向错误指令。
要获取错误指令的地址,只需获取保存的EIP
and CS
来自 ISR 堆栈中的值。 (如果您使用扁平内存模型并且所有段都覆盖整个 4GB,则保存的CS
当然,没有兴趣)。
movl 4(%esp), %eax
movw 8(%esp), %ebx
Now, EAX
包含保存的EIP
and EBX
被保存的CS
.
Edit:当然,正如指出的那样Alex https://stackoverflow.com/users/968261/alex in the comments https://stackoverflow.com/questions/10360888/identifying-faulting-address-on-general-protection-fault-x86/#comment13352050_10361732,如果#GP
是由内存访问引起的,并且您想要访问内存的地址,您将需要解码错误指令。