2012-04-28 36 views

回答

9

我在這裏所做的所有參考都是從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的指令。有關在 任務切換期間發生此異常時的後果的說明,請參閱第230頁上的「任務切換期間的例外情況」。

引用的部分提到下列:加載一個段 選擇一個任務切換過程中,可能會發生

異常。訪問TSS時也可能發生頁面錯誤。在這些 的情況下,硬件任務切換機制完成從TSS加載新的 任務狀態,然後觸發適當的例外 機制。沒有執行其他檢查。 發生這種情況時,保存的 指令指針指向新任務中的第一條指令。

因此,除非您正在使用硬件任務切換,否則保存的指令指針始終指向錯誤指令。

要獲取錯誤指令的地址,只需從ISR堆棧中獲取已保存的EIPCS值。 (如果您使用的是平板內存型號,並且您的所有細分受衆羣覆蓋整個4GB,那麼保存的CS當然不感興趣)。

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

現在,EAX包含保存EIPEBX保存CS

編輯:當然,作爲comments指出的Alex,以防#GP是由內存訪問造成的,你要訪問的內存地址,您需要將錯誤指令解碼。

+0

爲了得到實際地址(如果#GP是由存儲器訪問引起的),OP將需要解碼CS:EIP處的指令,並可能使用寄存器值替換爲各種ECX * 4 + EAX + 3。 – 2012-04-28 08:21:05

+0

@Alex:你說得對,我更新了答案。 – Job 2012-04-28 08:33:46

+0

謝謝喬布斯和亞歷克斯。 – 2012-04-28 18:01:51