识别常规保护错误(x86)上的错误地址

时间:2012-04-28 05:30:18

标签: operating-system x86 osdev interrupt-handling

我正在尝试在x86上为常规保护错误(GP#13)编写ISR。我无法从INTEL文档中找出如何找出导致异常的错误地址。我知道对于页面错误异常(GP#14),cr2寄存器保存了错误地址。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:10)

我在这里所做的所有引用都来自AMD64 Architecture Programmer's Manual Volume 2: System Programming,它也描述了传统的保护模式(即x86)行为。

图8-8在240页显示了中断到相同权限级别后的堆栈布局(即输入ISR时的堆栈布局):

Stack After Interrupt to Same Privilege Level

在8.2.14节中,您可以看到#GP提供了错误代码,以下内容也是您感兴趣的:

  

程序重启。 #GP是一个错误类型的异常。在大多数情况下,   保存的指令指针指向导致该指令的指令   #GP。有关在a期间发生此异常的后果的说明,请参见第230页中的“任务切换期间的异常”   任务切换。

引用的部分提及以下内容:

  

加载段时,任务切换期间可能会发生异常   选择。访问TSS时也会发生页面错误。在这些   例如,硬件任务切换机制完成加载新的   来自TSS的任务状态,然后触发相应的异常   机制。没有进行其他检查。 发生这种情况时,保存   指令指针指向新任务中的第一条指令。

因此,除非您使用硬件任务切换,否则保存的指令指针始终指向错误指令。

要获取错误指令的地址,只需从ISR中的堆栈中获取已保存的EIPCS值。 (如果您使用的是平面内存模型,并且所有细分都覆盖了整个4GB,那么保存的CS当然没有意义。

movl 4(%esp), %eax
movw 8(%esp), %ebx

现在,EAX包含已保存的EIPEBX已保存的CS

修改当然,正如Alex中的comments所指出的,如果#GP是由内存访问引起的,并且您希望在访问的内存地址中,您需要解码故障指令。