Operating system 识别一般保护故障的故障地址(x86)

Operating system 识别一般保护故障的故障地址(x86),operating-system,x86,osdev,interrupt-handling,Operating System,X86,Osdev,Interrupt Handling,我正在尝试为x86上的一般保护故障(GP#13)编写ISR。我无法从INTEL文档中找出导致异常的错误地址。我知道对于页面错误异常(GP#14),cr2寄存器保存错误地址。非常感谢您的帮助。我在这里所做的所有参考都来自,其中还描述了传统保护模式(即x86)的行为 第240页的图8-8显示了中断到相同权限级别后的堆栈布局(即,输入ISR时的堆栈布局): 在第8.2.14节中,您可以看到#GP提供了一个错误代码,以下内容也很有趣: 程序重新启动。GP属于故障类型异常。在大多数情况下 保存的指令指针

我正在尝试为x86上的一般保护故障(GP#13)编写ISR。我无法从INTEL文档中找出导致异常的错误地址。我知道对于页面错误异常(GP#14),cr2寄存器保存错误地址。非常感谢您的帮助。

我在这里所做的所有参考都来自,其中还描述了传统保护模式(即x86)的行为

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

在第8.2.14节中,您可以看到
#GP
提供了一个错误代码,以下内容也很有趣:

程序重新启动。
GP
属于故障类型异常。在大多数情况下 保存的指令指针指向导致错误的指令
#GP
。请参阅第230页的“任务切换期间的异常”,了解在任务切换期间发生该异常的后果说明 任务切换

参考章节提到以下内容:

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

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

要获取故障指令的地址,只需从ISR中的堆栈中获取保存的
EIP
CS
值。(如果您使用的是平板内存模型,并且您的所有数据段都覆盖了整个4GB,那么保存的
CS
当然不感兴趣)

现在,
EAX
包含保存的
EIP
EBX
保存的
CS


编辑:当然,正如中所指出的,如果
#GP
是由内存访问引起的,并且您需要访问内存的地址,则需要解码错误指令。

并获取实际地址(如果#GP是由内存访问引起的),OP需要在CS:EIP处解码指令,并可能使用寄存器值替换为各种ECX*4+EAX+3。
movl 4(%esp), %eax
movw 8(%esp), %ebx