实地址模式与保护模式下的中断与异常处理
1.中斷向量表
在實地址模式下,80486 CPU的中斷響應是根據(jù)中斷源提供的中斷類型號,查找中斷向量表,獲取中斷向量,繼而轉去執(zhí)行中斷處理。
中斷向量表位于內(nèi)存底端的1KB RAM區(qū),地址范圍為0000H~03FFH,如圖6.5所示。256種中斷類型由中斷類型號0~255(00H~FFH)表示。中斷類型號n與其對應中斷向量表的地址V的關系是:V=4n。約定4n+0和4n+1單元存放中斷服務子程序的偏移地址IP的值,4n+2和4n+3單元存放中斷服務子程序的段基址CS的值。CPU響應中斷請求后,由中斷源自動給出中斷類型號n送入CPU,由CPU自動完成向量表地址4n的運算,從向量表中取出中斷服務子程序的入口地址送入CS和IP中,將執(zhí)行的流程控制轉移到中斷服務子程序。
內(nèi)部中斷的向量地址由系統(tǒng)負責裝入,用戶不能隨意修改。用戶中斷的向量地址在初始化編程時裝入
圖6.5 中斷向量
2.設置中斷向量
用戶在應用系統(tǒng)中使用中斷時,需要在初始化程序中將中斷服務子程序的入口地址裝入中斷向量表指定的存儲單元中,以便在CPU響應中斷請求后,由中斷向量自動引導到中斷服務子程序。中斷向量的設置,既可以使用傳送指令直接裝入指定單元,也可以使用DOS系統(tǒng)功能調(diào)用 INT 21H中的25H號功能調(diào)用裝入。
(1)用傳送指令直接裝入
采用這種方法設置中斷向量,就是將中斷服務子程序的入口地址,通過數(shù)據(jù)傳送指令直接送入中斷向量表指定的單元中,即可完成中斷向量的設置。例如,設某中斷源的中斷類型號n為40H,中斷服務子程序的入口地址為INT-P,設置中斷向量的程序段如下:
CLI ; IF=0, 關中斷
MOV AX, 0 ; ES指向0段
MOV ES, AX
MOV BX, 40H×4 ; 向量表地址送BX
MOV AX, OFFSET INT-P ; 中斷服務子程序的偏移地址送AX
MOV ES:WORD PTR[BX], AX ; 中斷服務子程序的偏移地址寫入向量表
MOV AX, SEG INT-P ??????? ; 中斷服務子程序的段基址送AX
MOV ES:WORD PTR[BX+2],AX ; 中斷服務子程序的段基址寫入向量表
STI ; IF=1,開中斷
…
INT-P: … ??????????????? ; 中斷服務子程序
…
IRET ????????????????????? ; 中斷返回
(2)用DOS系統(tǒng)功能調(diào)用裝入
在DOS INT 21H系統(tǒng)功能調(diào)用中,用25H號功能可設置中斷向量,用35H號功能可獲取中斷向量。
25H號功能調(diào)用的入口參數(shù)是:
(AH) = 25H
(AL) = 中斷類型號
(DS:DX) = 中斷服務子程序的入口地址
例如,設某中斷的中斷類型號n為40H,中斷服務子程序的入口地址為INT-P,調(diào)用25H號功能裝入中斷向量的程序段如下:
CLI ; IF=0,關中斷
MOV AL, 40H ; 中斷類型號40H送AL
MOV DX, SEG INT-P ? ; 中斷服務子程序的段基址送DS
MOV DS, DX
MOV DX, OFFSET INT-P ; 中斷服務子程序的偏移地址送DX
MOV AH,25H ??????????? ; 25H功能調(diào)用
INT 21H
STI ; IF=1,開中斷
…
INT-P: … ; 中斷服務子程序
…
IRET ; 中斷返回
35H號功能調(diào)用的入口參數(shù)是:
(AH) = 35H
(AL) = 中斷類型號
出口參數(shù)是:
(ES:BX) = 中斷服務子程序的入口地址
例如,若從中斷類型號為40H對應的向量表中取出中斷向量,程序段如下。
MOV AH, 35H
MOV AL, 40H
INT 21H
該程序段執(zhí)行之后,從向量表中獲取的中斷向量存放在ES和BX中,ES中存放段基址,BX中存放偏移地址。
在實際應用中,為了不破壞向量表中的原始設置,通常在裝入新的中斷向量之前,先將原有的中斷向量取出保存,待中斷處理完畢,再將原中斷向量恢復。
3.中斷處理
當CPU工作在實地址模式下時,可以響應和處理外部中斷NMI和INTR,內(nèi)部中斷類型0, 1, 3, 4, 5, 6, 7, 8, 9, 12, 13, 16,共12種異常。
按任務輕重緩急程度,系統(tǒng)規(guī)定中斷處理的優(yōu)先順序是:內(nèi)部中斷優(yōu)先權最高(類型1單步除外),其次為NMI,再次是INTR,單步中斷優(yōu)先權最低。
實地址模式下的中斷處理流程如圖6.6所示。
圖6.6 實地址模式下的中斷處理流程
CPU在當前指令執(zhí)行完畢后,按中斷源的優(yōu)先順序去檢測和查詢是否有中斷請求,當查詢到有內(nèi)部中斷發(fā)生時,中斷類型號n由CPU內(nèi)部形成或由指令本身(INT n)提供;當查詢到有NMI請求時,自動轉入中斷類型2進行處理;當查詢到有INTR請求時,響應的條件是中斷標志位IF=1,其中斷類型號n由請求設備在中斷響應周期自動給出;當查詢到單步請求TF=1時,并且在IF=1時自動轉入中斷類型1進行處理。對于INTR請求引起的中斷,CPU要連續(xù)產(chǎn)生兩個低電平有效的中斷響應周期,進行中斷處理。
為了實現(xiàn)中斷服務子程序與主程序之間的跳轉與返回,CPU在響應中斷請求后,執(zhí)行中斷處理前,由硬件自動地完成如下操作:
?、?獲取中斷類型號n,生成中斷向量表地址4n。
?、?標志寄存器FR的內(nèi)容壓入堆棧保存。
?、?先將IF的值保存在TEMP中,然后將TF和IF清除,在中斷響應過程中,禁止單步執(zhí)行功能和再次響應新的INTR請求。
?、?斷點CS:IP壓入堆棧保存。
?、?從中斷向量表地址為4n的存儲單元中取出中斷向量送入CS和IP,繼而轉去執(zhí)行中斷服務子程序。斷點和標志位的出棧,是在中斷服務子程序結束后由中斷返回指令IRET來完成的。
為了支持多任務操作和虛擬存儲管理,80486 CPU可以工作于保護模式。在保護模式下,為每一個中斷和異常定義了一個中斷描述符,來說明中斷和異常服務程序的入口地址的屬性,所有的中斷描述符都集中存放在中斷描述符表(IDT)中,由中斷描述符表取代實地址模式下的中斷向量表。
1.中斷描述符與中斷描述符表
中斷描述符又稱中斷門,它用于描述中斷和異常處理程序的屬性。
與實地址模式下的中斷向量一樣,保護模式下的中斷描述符也充當引導程序到服務程序初始點執(zhí)行的指針。不同之處在于,在保護模式下,中斷描述符要占據(jù)連續(xù)的8個字節(jié)單元。
中斷描述符如圖6.7所示:
圖6.7 中斷描述符
圖6.7中低地址的0和1兩個字節(jié)是中斷代碼的偏移量A15~A0;
高地址的6和7兩個字節(jié)是中斷代碼的偏移量A31~A16;
2和3兩個字節(jié)是段選擇符,段選擇符和偏移量用來形成中斷服務子程序的入口地址;
4和5兩個字節(jié)稱為訪問權限字節(jié),它標識該中斷描述符是否有效、服務程序的特權級和描述符的類型等信息。
具體描述如下:
P(present):表示中斷描述符的有效性。P=1,中斷描述符有效;P=0,中斷描述符無效。
DPL(descriptor privilege level):表示中斷優(yōu)先級,是系統(tǒng)描述符被訪問的特權級,DPL占用2位,有4種編碼:00, 01, 10和11,共4級特權級,0級優(yōu)先級最高。
TYPE:指示中斷描述符的不同類型,占用4位,在中斷描述符表中有3種類型的描述符:任務門、中斷門和自陷門。例如,1110指示32位中斷門,1111指示32位自陷門,0101指示32位任務門。
中斷描述符表相當于實地址模式下的中斷向量表,用于存放中斷描述符。表中最多可以包含256個中斷描述符,每個中斷描述符占用連續(xù)的8個字節(jié),因此IDT共占用2KB存儲空間,可以放在80486 CPU物理地址空間的任何地方,該表的位置和大小由中斷描述符表寄存器IDTR的值確定。
IDTR包含32位的基地址和16位段限,基地址定義中斷描述符表IDT在存儲器中的起始點,段限定義中斷描述符表所占的字節(jié)個數(shù)。
2.中斷調(diào)用
保護模式下中斷調(diào)用過程如圖6.8所示。
當CPU響應外部中斷請求或執(zhí)行某條指令產(chǎn)生異常時,根據(jù)中斷或異常的類型號n,從中斷描述符表(IDT)中找到相應的中斷門,由中斷描述符中的段選擇符指向全局描述符表(GDT)或局部描述符表(LDT)中的目標段描述符,此目標段描述符內(nèi)的段基址指向中斷服務子程序代碼段的基地址,由該基地址與中斷描述符中的偏移量之和形成中斷服務子程序的入口地址。
具體實現(xiàn)方法如下:
根據(jù)中斷類型號n,得到中斷門在IDT中的起始地址,
即:起始地址=IDT的基地址+n×8
由中斷門中的段選擇符,從GDT或LDT中取出段描述符。
根據(jù)段描述符中提供的段基址和中斷描述符中提供的偏移地址,合成中斷服務子程序的入口地址。
?
圖6.8 保護模式下中斷調(diào)用過程
總結
以上是生活随笔為你收集整理的实地址模式与保护模式下的中断与异常处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 80486保护模式存储管理
- 下一篇: 用bochs调试自己写的系统引导代码