中斷描述符表(Interrupt Descriptor Table,IDT)將每個異常或
中斷向量分別與它們的處理過程聯系起來。與GDT和LDT表類似,IDT也是由8字節長描述符組成的一個數組。
#pragma pack(push, 1) //IDT的內存空間是一個數組。每個元素都有如下的結構 typedef struct P2C_IDT_ENTRY_ { P2C_U16 offset_low; P2C_U16 selector; P2C_U8 reserved; P2C_U8 type:4; P2C_U8 always0:1; P2C_U8 dpl:2; P2C_U8 present:1; P2C_U16 offset_high; }P2C_IDTENTRY, *PP2C_IDTENTRY; #pragma pack(pop)
中斷描述符表
可以包含描述符。為了構成IDT表中的一個索引值,處理器把異常或中斷的向量號乘以8。因為最多只
有256個中斷或異常向量,所以IDT無需包含多於256個描述符。IDT中可以含有少於256個描述符,因為
只有可能發生的異常或中斷才需要描述符。不過IDT中所有空描述符項應該設置其存在位(標志)為0
// //現在這個中斷門沒有用了,設置type = 0使之空閑 // idt_addr[old_id].type = 0;
。
中含有IDT表32位的基地址和16位的長度(限長)值。IDT表基地址應該對齊在8
字節邊
界上以提高處理器的訪問效率。限長值是以
字節為單位的IDT表的長度。
#pragma pack(push, 1) //從sidt指令獲得一個如下的結構,從這里可以得到IDT的開始地址 typedef struct P2C_IDTR_ { P2C_U16 limit; // 范圍 P2C_U32 base; //基地址 }P2C_IDTR, *PP2C_IDTR; #pragma pack(pop)
中斷描述符表IDT和寄存器IDTR
LIDT和SIDT指令分別用於加載和保存IDTR寄存器的內容。
LIDT指令用於把內存中的限長值和基地址操作數加載到IDTR寄存器中。該指令僅能由當前
特權級CPL是0的代碼執行,通常被用於創建IDT時的操作
系統初始化代碼中。
SIDT指令用於把IDTR中的基地址和限長內容復制到內存中。該指令可在任何特權
級上執行。
VOID *p2cGetIdt() { PAGED_CODE(); P2C_IDTR idtr; // //一句匯編讀取到IDT的位置 // _asm sidt idtr; return (void *)idtr.base; }
如果中斷或異常向量引用的描述符超過了IDT的界限,處理器會產生一個一般保護性異常
在實地址模式中,
CPU把內存中從0開始的1K字節作為一個中斷向量表。表中的
每個表項占四個字節,由兩個字節的
段地址和兩個字節的
偏移量組成,這樣構成的地址便是相應
中斷處理程序的入口地址。但是,在保護模式下,由四
字節的表項構成的
中斷向量表顯然滿足不了要求。這是因為,除了兩個字節的
段描述符,
偏移量必用四字節來表示;‚要有反映
模式切換的信息


在保護模式下,
中斷向量表中的表項由8個字節組成,中斷向量表也改叫做中斷描述符表IDT(InterruptDescriptor Table)。其中的每個表項叫做一個門描述符(gate descriptor),“門”的含義是當中斷發生時必須先通過這些門,然后才能進入相應的處理程序。
#pragma pack(push, 1) //IDT的內存空間是一個數組。每個元素都有如下的結構 typedef struct P2C_IDT_ENTRY_ { P2C_U16 offset_low; P2C_U16 selector; P2C_U8 reserved; P2C_U8 type:4; P2C_U8 always0:1; P2C_U8 dpl:2; P2C_U8 present:1; P2C_U16 offset_high; }P2C_IDTENTRY, *PP2C_IDTENTRY; #pragma pack(pop)
主要門描述符是:
· 中斷門(Interrupt gate)
其類型碼為110,中斷門包含了一個中斷或
異常處理程序所在段的選擇符和段內
偏移量。當控制權通過中斷門進入
中斷處理程序時,處理器清IF標志,即關中斷,以避免嵌套中斷的發生。中斷門中的DPL(Descriptor Privilege Level)為0,因此,用戶態的進程不能訪問Intel的中斷門。所有的
中斷處理程序都由中斷門激活,並全部限制在
內核態。
·
陷阱門(Trap gate)
其類型碼為111,與中斷門類似,其唯一的區別是,控制權通過
陷阱門進入處理程序時維持IF標志位不變,也就是說,不關中斷。
· 系統門(System gate)
這是Linux內核特別設置的,用來讓用戶態的進程訪問Intel的
陷阱門,因此,門描述符的DPL為3。通過系統門來激活4個Linux
異常處理程序,它們的向量是3、4、5及128,也就是說,在用戶態下,可以使用int3、into、bound 及int0x80四條
匯編指令。
最后,在保護模式下,中斷描述符表在內存的位置不再限於從地址0開始的地方,而是可以放在內存的任何地方。為此,CPU中增設了一個中斷描述符表寄存器IDTR,用來存放中斷描述符表在內存的起始地址。中斷描述符表寄存器IDTR是一個48位的寄存器,其低16位保存中斷描述符表的大小,高32位保存IDT的
基址.