中斷/例外處理

錯誤碼


錯誤碼格式

在有些例外中(參考「中斷/例外處理」中的「簡介」),處理器會在堆疊中推入錯誤碼。錯誤碼是用來指出發生例外的地方(segment)。錯誤碼很類似 segment selector(參考「記憶體管理」中的「分段架構」),其格式如下:
其中的 EXT 若為 1,則表示例外因為程式以外的事件而產生的。IDT 若為 1,則是表示索引是指向 IDT 中的 descriptor,若為 0,則表示索引是指向 LDT 或 GDT。若索引是指向 LDT 或 GDT,則由 TI 來決定。TI 為 1 表示索引是指向 LDT,反之則表示索引是指向 GDT。索引的意義則和 segment selector 中的索引值相同。
有時候,錯誤碼的低字組(即第 0 bit 到第 15 bit)均為 0,這時表示這個例外並不和某個特定的 segment 有關,或是例外是因為存取 null segment 而造成的。
在中斷處理結束後,會執行 IRET 返回原程式。但是,IRET 並不會將錯誤碼由堆疊中彈出,因此,中斷處理程序中要先把錯誤碼彈出後,才能使用 IRET 返回,否則會返回到不正確的位址。
 

分頁錯誤的錯誤碼

發生分頁錯誤例外時,錯誤碼的格式和上面所示的不同。分頁錯誤的錯誤碼格式如下:
其中,P 為 0 表示因為分頁不存在而導致例外;反之,則表示是因為違反保護規則才導致例外。而 W/R 若為 0 則表示是在讀取分頁時發生例外,反之則表示是在寫入分頁時發生例外。而 U/S 為 0 表示例外是在 supervisor 模式下發生的;反之則表示例外是在 user 模式下發生的。最後,RSVD 為 1 表示在 CR4 中的 PSE 或 PAE 設為 1,且分頁目錄中的「保留」位元中有些 bit 被設為 1,而導致例外;反之,則表示例外是因為其它原因而發生的。
在發生分頁錯誤的例外時,處理器會把發生例外的位址(線性位址)存到 CR2 中。例外處理程序可以利用這個位址找出發生例外的分頁。如果在分頁錯誤處理程序中,有可能會再發生分頁錯誤,則分頁錯誤處理程序必須在發生新的分頁錯誤之前,把 CR2 存到堆疊中。