軟件調試(2) - 異常中斷與中斷向量表(IDT)簡介

IA-32 中斷異常列表:
No. 助記符 類型 描述 來源

0 #DE 錯誤 除零錯誤 div / idiv指令
1 #DB 錯誤/陷阱 調試異常 任何代碼或數據引用
2 中斷 NMI中斷 不可屏蔽的外部中斷
3 #BP 陷阱 斷點 INT3指令
4 #OF 陷阱 溢出 INT0指令
5 #BR 錯誤 數組出界 BOUND指令
6 #UD 錯誤 無效指令(沒定義) UD2指令
7 #NM 錯誤 數學協處理器不存在 浮點或WAIT/FWAIT指令
8 #DF 中止 雙重錯誤 任何可能產生異常的指令/任意中斷
9 #MF 錯誤 向協處理器傳送操作數, 浮點指令
時檢測到頁錯誤,或段不存
在.
10 #TS 錯誤 無效TSS(任務狀態段) 任務切換或訪問TSS
11 #NP 錯誤 段不存在 加載段寄存器或訪問系統段
12 #SS 錯誤 棧段錯誤 棧操作或加載SS寄存器
13 #GP 錯誤 通用保護(GP)異常,如果 任何內存引用和保護性檢測
一個操作違反了保護模式
下的約定,而且該情況不屬
於其他異常,則產生GP
14 #PF 錯誤 頁錯誤 任何內存引用
15 保留
16 #MF 錯誤 浮點錯誤 浮點或WAIT/FWAIT指令
17 #AC 錯誤 對齊檢查 對內存中數據的引用
18 #MC 中止 機器檢查 錯誤代碼和來源與型號有關
19 #XF 錯誤 SIMD浮點異常 SIMD浮點指令
20 保留
32-255 用戶自定義中斷 可屏蔽中斷

錯誤代碼
31 3 2 1 0
----保留--------------- -TI- -IDT- -EXT-

位0: EXT 如果為1表示外部事件導致異常
位1: IDT 描述符位置,如果為1表示錯誤碼的段選擇子索引指向的是IDT表中的門描述符,如果0表示索引部份指向的是LDT/GDT的描述符
位2: TI(GDT/LDT, 當IDT位為0時有效), 0:GDT / 1:LDT


IA-32中斷異常的優先級

1(最高級) 硬件重啟動和機器檢查異常
2 任務切換陷阱

3 外部硬件(例如芯片組)通過CPU引腳發給CPU的特別干預
#FLUSH
#STPCLK
#SMI
#INIT

4 上一指令導致的陷阱
INT3
調用陷阱,EFLAGS[TF]=1 或調試寄存器 或 輸入輸出斷點

5 不可屏蔽中斷 NMI
6 可屏蔽中斷
7 代碼斷點錯誤異常
8 下一條指令錯誤 代碼段長度/代碼內存頁錯誤(即代碼屬性的內存頁導致頁錯誤)
9 解碼下一指令時檢測到錯誤
1.指令長度大於15字節
2.非法操作碼
3.協處理器不可用

10(最低) 執行指令時檢測到的錯誤
1.溢出, 當EFLAGS[OF] = 1 時執行INTO指令
2.執行BOUND指令時檢測到邊界錯誤
3.無效的TSS
4.段不存在
5.棧異常
6.一般保護異常
7.數據頁錯誤
8.對齊檢查異常
9.X86 FPU異常
10.SIMD浮點異常
P.S. IA-32中所有中斷優先級一樣, 但同一優先級的優先次序被CPU型號影響


IDT的初始化-> 通常(操作系統/BIOS固件)在系統初始化時就準備好中斷處理例程及IDT表
然後把IDT表的位置通過IDTR(IDR Register)寄存器告訴cpu

IDTR -> 48字節

48--------------------16------------0
IDT表基址 IDT表邊界(以字節為單位的最大偏移量)

LIDT和SIDT指令分別用來從內存變量 加載IDTR和把IDTR的值存儲到內存變量, 只有在RING0下才可以執行
關機後會把IDTR設成=>0X0000, 最大偏移設成=>0XFFFF 為實模式中斷向量表設置

實模式下中斷或異常程序

1. 將CS和EIP(低16位)壓入棧
2. 將EFLASG的低16位壓入堆棧
3. 清除IF,禁止其他中斷
4. 消除TF,RF,AC標志
5. 使用向量號N作為索引, 在IVT中找到對應(N*4+IVT表基地址)
6. 將表項中的段地址和偏移地址分別裝入CS:EIP,開始執行異常/中斷處理代碼
7. 中斷例程總是以IRET指令結束=>彈出CS:EIP,和被清除的標志位,然後返回被中斷的位置


參考:Windows軟件調試

Comments

Popular posts from this blog

Android Kernel Development - Kernel compilation and Hello World

How does Nested-Virtualization works?

Understanding ACPI and Device Tree