我正在尝试在x86上为常规保护错误(GP#13)编写ISR。我无法从INTEL文档中找出如何找出导致异常的错误地址。我知道对于页面错误异常(GP#14),cr2寄存器保存了错误地址。任何帮助表示赞赏。
答案 0 :(得分:10)
我在这里所做的所有引用都来自AMD64 Architecture Programmer's Manual Volume 2: System Programming,它也描述了传统的保护模式(即x86)行为。
图8-8在240页显示了中断到相同权限级别后的堆栈布局(即输入ISR时的堆栈布局):
在8.2.14节中,您可以看到#GP
提供了错误代码,以下内容也是您感兴趣的:
程序重启。
#GP
是一个错误类型的异常。在大多数情况下, 保存的指令指针指向导致该指令的指令#GP
。有关在a期间发生此异常的后果的说明,请参见第230页中的“任务切换期间的异常” 任务切换。
引用的部分提及以下内容:
加载段时,任务切换期间可能会发生异常 选择。访问TSS时也会发生页面错误。在这些 例如,硬件任务切换机制完成加载新的 来自TSS的任务状态,然后触发相应的异常 机制。没有进行其他检查。 发生这种情况时,保存 指令指针指向新任务中的第一条指令。
因此,除非您使用硬件任务切换,否则保存的指令指针始终指向错误指令。
要获取错误指令的地址,只需从ISR中的堆栈中获取已保存的EIP
和CS
值。 (如果您使用的是平面内存模型,并且所有细分都覆盖了整个4GB,那么保存的CS
当然没有意义。
movl 4(%esp), %eax
movw 8(%esp), %ebx
现在,EAX
包含已保存的EIP
和EBX
已保存的CS
。
修改当然,正如Alex中的comments所指出的,如果#GP
是由内存访问引起的,并且您希望在访问的内存地址中,您需要解码故障指令。