任務(wù)門(mén),調(diào)用門(mén),中斷門(mén),陷阱門(mén)
每個(gè)任務(wù)有一個(gè)任務(wù)狀態(tài)段TSS,用于保存任務(wù)的有關(guān)信息,在任務(wù)內(nèi)變換特權(quán)級(jí)和任務(wù)切換時(shí),要用到這些信息。為了控制任務(wù)內(nèi)發(fā)生特權(quán)級(jí)變換的轉(zhuǎn)移,為了控制任務(wù)切換,一般要通過(guò)控制門(mén)進(jìn)行這些轉(zhuǎn)移。本文將介紹任務(wù)狀態(tài)段和控制門(mén)。
<一>系統(tǒng)段描述符
系統(tǒng)段是為了實(shí)現(xiàn)存儲(chǔ)管理機(jī)制所使用的一種特別的段。在80386中,有兩種系統(tǒng)段:任務(wù)狀態(tài)段TSS和局部描述符表LDT段。用于描述系統(tǒng)段的描述符稱(chēng)為系統(tǒng)段描述符。
1.系統(tǒng)段描述符的格式
系統(tǒng)段描述符的一般格式如下表所示。
系統(tǒng)段
描述符m+7m+6m+5m+4m+3m+2m+1m+0
Base(31...24)AttributesSegment Base(23...0)Segment Limite(15...0)
系統(tǒng)段
描述符
的屬性Byte m+6Byte m+5
BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0
GX0AVLLimit(19...16)PDPLDT0TYPE
與存儲(chǔ)段描述符相比,它們很相似,區(qū)分的標(biāo)志是屬性字節(jié)中的描述符類(lèi)型位DT的值。DT=1表示存儲(chǔ)段,DT=0表示系統(tǒng)段。系統(tǒng)段描述符中的段基地址和段界限字段與存儲(chǔ)段描述符中的意義完全相同;屬性中的G位、AVL位、P位和DPL字段的作用也完全相同。存儲(chǔ)段描述符屬性中的D位在系統(tǒng)段描述符中不使用,現(xiàn)用符號(hào)X表示。系統(tǒng)段描述符的類(lèi)型字段TYPE仍是4位,其編碼及表示的類(lèi)型列于下表,其含義與存儲(chǔ)段描述符的類(lèi)型卻完全不同。
系統(tǒng)段
類(lèi) 型類(lèi)型編碼說(shuō) 明
0未定義
1可用286TSS
2LDT
3忙的286TSS
4286調(diào)用門(mén)
5任務(wù)門(mén)
6286中斷門(mén)
7286陷阱門(mén)
系統(tǒng)段
類(lèi) 型類(lèi)型編碼說(shuō) 明
8未定義
9可用386TSS
A未定義
B忙的386TSS
C386調(diào)用門(mén)
D未定義
E386中斷門(mén)
F386陷阱門(mén)
從上表可見(jiàn),只有類(lèi)型編碼為2、1、3、9和B的描述符才是真正的系統(tǒng)段描述符,它們用于描述系統(tǒng)段LDT和任務(wù)狀態(tài)段TSS,其它類(lèi)型的描述符是門(mén)描述符。
利用前文定義的存儲(chǔ)段描述符結(jié)構(gòu)類(lèi)型DESC仍能方便地在程序中說(shuō)明系統(tǒng)段描述符。需要注意的是,系統(tǒng)段描述符的選擇子不能用來(lái)讀寫(xiě)系統(tǒng)段,要想讀寫(xiě)系統(tǒng)段,必須使用別名技術(shù)。
2.LDT段描述符
LDT段描述符描述任務(wù)的局部描述符表段。例如:下面的描述符LDTABLE描述一個(gè)局部描述符表段,基地址是654321H,以字節(jié)為單位的界限是1FH,描述符特權(quán)級(jí)是0。
LDTABLE DESC <1FH,4321H,65H,82H,,>
LDT段描述符必須安排在全局描述符表中才有效。在裝載LDTR寄存器時(shí),描述符中的LDT段基地址和段界限等信息被裝入LDT段描述符高速緩沖寄存器中。
3.任務(wù)狀態(tài)段描述符
任務(wù)狀態(tài)段TSS用于保存任務(wù)的各種狀態(tài)信息。任務(wù)狀態(tài)段描述符描述某個(gè)任務(wù)狀態(tài)段TSS描述符分為286TSS和386TSS兩類(lèi)。TSS描述符規(guī)定了任務(wù)狀態(tài)段的基地址和任務(wù)狀態(tài)段的大小等信息。例如,下面的描述符TempTask描述一個(gè)可用的386任務(wù)狀態(tài)段,基地址是123456H,以字節(jié)為單位的界限是104,描述符特權(quán)級(jí)是0。
TempTask DESC <104,3456H,12H,89H,,>
在裝載任務(wù)狀態(tài)段寄存器TR時(shí),描述符中的段基地址和段界限等信息被裝入到TR的高速緩沖寄存器中。在任務(wù)切換或執(zhí)行LTR指令時(shí),要裝載TR寄存器。
TSS描述符中的類(lèi)型規(guī)定:TSS要么為“忙”,要么為“可用”。如果一個(gè)任務(wù)是當(dāng)前正執(zhí)行的任務(wù),或者是用TSS中的鏈接字段沿掛起任務(wù)鏈接到當(dāng)前任務(wù)上的任務(wù),那么該任務(wù)是“忙”的任務(wù);否則該任務(wù)為“可用”任務(wù)。
利用段間轉(zhuǎn)移指令JMP和段間調(diào)用指令CALL,直接通過(guò)TSS描述符或通過(guò)任務(wù)門(mén)可實(shí)現(xiàn)任務(wù)切換。
<二>門(mén)描述符
除存儲(chǔ)段描述符和系統(tǒng)段描述符外,還有一類(lèi)門(mén)描述符。門(mén)描述符并不描述某種內(nèi)存段,而是描述控制轉(zhuǎn)移的入口點(diǎn)。這種描述符好比一個(gè)同向另一代碼段的門(mén)。通過(guò)這種門(mén),可實(shí)現(xiàn)任務(wù)內(nèi)特權(quán)級(jí)的變換和任務(wù)間的切換。所以,這種門(mén)描述符也稱(chēng)為控制門(mén)。
1.門(mén)描述符的一般格式
門(mén)描述符的一般格式如下圖所示。門(mén)描述符只有位于描述符內(nèi)偏移5的類(lèi)型字節(jié)與系統(tǒng)段保持一致,也由該字節(jié)標(biāo)示門(mén)描述符和系統(tǒng)段描述符。該字節(jié)內(nèi)的P和DPL的意義與其它描述符種中的意義相同。其它字節(jié)主要用于存放一個(gè)48位的全指針(16位的選擇子和32位的偏移量)。
門(mén)描述符m+7m+6m+5m+4m+3m+2m+1m+0
Offset(31...16)AttributesSelectorOffset(15...0)
門(mén)描述
符屬性Byte m+5Byte m+4
BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0
PDPLDT0TYPE000Dword Count
根據(jù)上圖給出的門(mén)描述符的結(jié)構(gòu),可定義如下的門(mén)描述符結(jié)構(gòu)類(lèi)型:
GATE STRUC ;門(mén)結(jié)構(gòu)類(lèi)型定義 OFFSETL DW 0 ;32位偏移的低16位 SELECTOR DW 0 ;選擇子 DCOUNT DB 0 ;雙字計(jì)數(shù)字段 GTYPE DB 0 ;類(lèi)型 OFFSETH DW 0 ;32位偏移的高16位 GATE ENDS
利用門(mén)描述符結(jié)構(gòu)類(lèi)型GATE能方便地在程序中說(shuō)明門(mén)描述符。
例如,下面的門(mén)描述符SUBRG描述一個(gè)386調(diào)用門(mén),門(mén)內(nèi)的選擇子是10H,入口偏移是123456H,門(mén)描述符特權(quán)級(jí)是3,雙字計(jì)數(shù)是0。
SUBRG GATE <3456,10H,,8CH+60H,12H>
從上述描述符類(lèi)型的列表中可見(jiàn),門(mén)描述符又可分為:任務(wù)門(mén)、調(diào)用門(mén)、中斷門(mén)和陷阱門(mén),并且除任務(wù)門(mén)外,其它描述符還各分成286和386兩種。
2.調(diào)用門(mén)
調(diào)用門(mén)描述某個(gè)子程序的入口。調(diào)用門(mén)內(nèi)的選擇子必須實(shí)現(xiàn)代碼段描述符,調(diào)用門(mén)內(nèi)的偏移是對(duì)應(yīng)代碼段內(nèi)的偏移。利用段間調(diào)用指令CALL,通過(guò)調(diào)用門(mén)可實(shí)現(xiàn)任務(wù)內(nèi)從外層特權(quán)級(jí)變換到內(nèi)層特權(quán)級(jí)。
在上圖所示的門(mén)描述符內(nèi)偏移4字節(jié)的位0至位4是雙字計(jì)數(shù)字段,該字段只在調(diào)用門(mén)描述符中有效,在其它門(mén)描述符中無(wú)效。主程序通過(guò)堆棧把入口參數(shù)傳遞給子程序,如果在利用調(diào)用門(mén)調(diào)用子程序時(shí)引起特權(quán)級(jí)的轉(zhuǎn)換和堆棧的改變,那么就需要將外層堆棧中的參數(shù)復(fù)制到內(nèi)層堆棧。該雙字計(jì)數(shù)字段就是用于說(shuō)明這種情況發(fā)生時(shí),要復(fù)制的雙字參數(shù)的數(shù)量。
3.任務(wù)門(mén)
任務(wù)門(mén)指示任務(wù)。任務(wù)門(mén)內(nèi)的選擇子必須指示GDT中的任務(wù)狀態(tài)段TSS描述符,門(mén)中的偏移無(wú)意義。任務(wù)的入口點(diǎn)保存在TSS中。利用段間轉(zhuǎn)移指令JMP和段間調(diào)用指令CALL,通過(guò)任務(wù)門(mén)可實(shí)現(xiàn)任務(wù)切換。
4.中斷門(mén)和陷阱門(mén)
中斷門(mén)和陷阱門(mén)描述中斷/異常處理程序的人口點(diǎn)。中斷門(mén)和陷阱門(mén)內(nèi)的選擇子必須指向代碼段描述符,門(mén)內(nèi)的偏移就是對(duì)應(yīng)代碼段的人口點(diǎn)的偏移。中斷門(mén)和陷阱門(mén)只有在中斷描述符表IDT中才有效。關(guān)于中斷門(mén)和陷阱門(mén)的區(qū)別將在以后的文章中論述。
<三>任務(wù)狀態(tài)段
任務(wù)狀態(tài)段(Task State Segment)是保存一個(gè)任務(wù)重要信息的特殊段。任務(wù)狀態(tài)段描述符用于描述這樣的系統(tǒng)段。任務(wù)狀態(tài)段寄存器TR的可見(jiàn)部分含有當(dāng)前任務(wù)的任務(wù)狀態(tài)段描述符的選擇子,TR的不可見(jiàn)的高速緩沖寄存器部分含有當(dāng)前任務(wù)狀態(tài)段的段基地址和段界限等信息。
TSS在任務(wù)切換過(guò)程中起著重要作用,通過(guò)它實(shí)現(xiàn)任務(wù)的掛起和恢復(fù)。所謂任務(wù)切換是指,掛起當(dāng)前正在執(zhí)行的任務(wù),恢復(fù)或啟動(dòng)另一任務(wù)的執(zhí)行。在任務(wù)切換過(guò)程中,首先,處理器中各寄存器的當(dāng)前值被自動(dòng)保存到TR所指定的TSS中;然后,下一任務(wù)的TSS的選擇子被裝入TR;最后,從TR所指定的TSS中取出各寄存器的值送到處理器的各寄存器中。由此可見(jiàn),通過(guò)在TSS中保存任務(wù)現(xiàn)場(chǎng)各寄存器狀態(tài)的完整映象,實(shí)現(xiàn)任務(wù)的切換。
任務(wù)狀態(tài)段TSS的基本格式如下圖所示。
任
務(wù)
狀
態(tài)
段
基
本
部
分
的
格
式BIT31—BIT16BIT15—BIT1BIT0Offset
0000000000000000鏈接字段0
ESP04
0000000000000000SS08
ESP10CH
0000000000000000SS110H
ESP214H
0000000000000000SS218H
CR31CH
EIP20H
EFLAGS24H
EAX28H
ECX2CH
EDX30H
EBX34H
ESP38H
EBP3CH
ESI40H
EDI44H
0000000000000000ES48H
0000000000000000CS4CH
0000000000000000SS50H
0000000000000000DS54H
0000000000000000FS58H
0000000000000000GS5CH
0000000000000000LDTR60H
I/O許可位圖偏移000000000000000T64H
從圖中可見(jiàn),TSS的基本格式由104字節(jié)組成。這104字節(jié)的基本格式是不可改變的,但在此之外系統(tǒng)軟件還可定義若干附加信息?;镜?04字節(jié)可分為鏈接字段區(qū)域、內(nèi)層堆棧指針區(qū)域、地址映射寄存器區(qū)域、寄存器保存區(qū)域和其它字段等五個(gè)區(qū)域。
1.寄存器保存區(qū)域
寄存器保存區(qū)域位于TSS內(nèi)偏移20H至5FH處,用于保存通用寄存器、段寄存器、指令指針和標(biāo)志寄存器。當(dāng)TSS對(duì)應(yīng)的任務(wù)正在執(zhí)行時(shí),保存區(qū)域是未定義的;在當(dāng)前任務(wù)被切換出時(shí),這些寄存器的當(dāng)前值就保存在該區(qū)域。當(dāng)下次切換回原任務(wù)時(shí),再?gòu)谋4鎱^(qū)域恢復(fù)出這些寄存器的值,從而,使處理器恢復(fù)成該任務(wù)換出前的狀態(tài),最終使任務(wù)能夠恢復(fù)執(zhí)行。
從上圖可見(jiàn),各通用寄存器對(duì)應(yīng)一個(gè)32位的雙字,指令指針和標(biāo)志寄存器各對(duì)應(yīng)一個(gè)32位的雙字;各段寄存器也對(duì)應(yīng)一個(gè)32位的雙字,段寄存器中的選擇子只有16位,安排再雙字的低16位,高16位未用,一般應(yīng)填為0。
2.內(nèi)層堆棧指針區(qū)域
為了有效地實(shí)現(xiàn)保護(hù),同一個(gè)任務(wù)在不同的特權(quán)級(jí)下使用不同的堆棧。例如,當(dāng)從外層特權(quán)級(jí)3變換到內(nèi)層特權(quán)級(jí)0時(shí),任務(wù)使用的堆棧也同時(shí)從3級(jí)變換到0級(jí)堆棧;當(dāng)從內(nèi)層特權(quán)級(jí)0變換到外層特權(quán)級(jí)3時(shí),任務(wù)使用的堆棧也同時(shí)從0級(jí)堆棧變換到3級(jí)堆棧。所以,一個(gè)任務(wù)可能具有四個(gè)堆棧,對(duì)應(yīng)四個(gè)特權(quán)級(jí)。四個(gè)堆棧需要四個(gè)堆棧指針。
TSS的內(nèi)層堆棧指針區(qū)域中有三個(gè)堆棧指針,它們都是48位的全指針(16位的選擇子和32位的偏移),分別指向0級(jí)、1級(jí)和2級(jí)堆棧的棧頂,依次存放在TSS中偏移為4、12及20開(kāi)始的位置。當(dāng)發(fā)生向內(nèi)層轉(zhuǎn)移時(shí),把適當(dāng)?shù)亩褩V羔樠b入SS及ESP寄存器以變換到內(nèi)層堆棧,外層堆棧的指針保存在內(nèi)層堆棧中。沒(méi)有指向3級(jí)堆棧的指針,因?yàn)?級(jí)是最外層,所以任何一個(gè)向內(nèi)層的轉(zhuǎn)移都不可能轉(zhuǎn)移到3級(jí)。
但是,當(dāng)特權(quán)級(jí)由內(nèi)層向外層變換時(shí),并不把內(nèi)層堆棧的指針保存到TSS的內(nèi)層堆棧指針區(qū)域。實(shí)際上,處理器從不向該區(qū)域進(jìn)行寫(xiě)入,除非程序設(shè)計(jì)者認(rèn)為改變?cè)搮^(qū)域的值。這表明向內(nèi)層轉(zhuǎn)移時(shí),總是把內(nèi)層堆棧認(rèn)為是一個(gè)空棧。因此,不允許發(fā)生同級(jí)內(nèi)層轉(zhuǎn)移的遞歸,一旦發(fā)生向某級(jí)內(nèi)層的轉(zhuǎn)移,那么返回到外層的正常途徑是相匹配的向外層返回。
3.地址映射寄存器區(qū)域
從虛擬地址空間到線性地址空間的映射由GDT和LDT確定,與特定任務(wù)相關(guān)的部分由LDT確定,而LDT又由LDTR確定。如果采用分頁(yè)機(jī)制,那么由線性地址空間到物理地址空間的映射由包含頁(yè)目錄表起始物理地址的控制寄存器CR3確定。所以,與特定任務(wù)相關(guān)的虛擬地址空間到物理地址空間的映射由LDTR和CR3確定。顯然,隨著任務(wù)的切換,地址映射關(guān)系也要切換。
TSS的地址映射寄存器區(qū)域由位于偏移1CH處的雙字字段(CR3)和位于偏移60H處的字字段(LDTR)組成。在任務(wù)切換時(shí),處理器自動(dòng)從要執(zhí)行任務(wù)的TSS中取出這兩個(gè)字段,分別裝入到寄存器CR3和LDTR。這樣就改變了虛擬地址空間到物理地址空間的映射。
但是,在任務(wù)切換時(shí),處理器并不把換出任務(wù)但是的寄存器CR3和LDTR的內(nèi)容保存到TSS中的地址映射寄存器區(qū)域。事實(shí)上,處理器也從來(lái)不向該區(qū)域自動(dòng)寫(xiě)入。因此,如果程序改變了LDTR或CR3,那么必須把新值人為地保存到TSS中的地址映射寄存器區(qū)域相應(yīng)字段中??梢酝ㄟ^(guò)別名技術(shù)實(shí)現(xiàn)此功能。
4.鏈接字段
鏈接字段安排在TSS內(nèi)偏移0開(kāi)始的雙字中,其高16位未用。在起鏈接作用時(shí),地16位保存前一任務(wù)的TSS描述符的選擇子。
如果當(dāng)前的任務(wù)由段間調(diào)用指令CALL或中斷/異常而激活,那么鏈接字段保存被掛起任務(wù)的 TSS的選擇子,并且標(biāo)志寄存器EFLAGS中的NT位被置1,使鏈接字段有效。在返回時(shí),由于NT標(biāo)志位為1,返回指令RET或中斷返回指令I(lǐng)RET將使得控制沿鏈接字段所指恢復(fù)到鏈上的前一個(gè)任務(wù)。
5.其它字段
為了實(shí)現(xiàn)輸入/輸出保護(hù),要使用I/O許可位圖。任務(wù)使用的I/O許可位圖也存放在TSS中,作為T(mén)SS的擴(kuò)展部分。在TSS內(nèi)偏移66H處的字用于存放I/O許可位圖在TSS內(nèi)的偏移(從TSS開(kāi)頭開(kāi)始計(jì)算)。關(guān)于I/O許可位圖的作用,以后的文章中將會(huì)詳細(xì)介紹。
在TSS內(nèi)偏移64H處的字是為任務(wù)提供的特別屬性。在80386中,只定義了一種屬性,即調(diào)試陷阱。該屬性是字的最低位,用T表示。該字的其它位置被保留,必須被置為0。在發(fā)生任務(wù)切換時(shí),如果進(jìn)入任務(wù)的T位為1,那么在任務(wù)切換完成之后,新任務(wù)的第一條指令執(zhí)行之前產(chǎn)生調(diào)試陷阱。
6.用結(jié)構(gòu)類(lèi)型定義TSS
根據(jù)上圖給出的任務(wù)狀態(tài)段TSS的結(jié)構(gòu),可定義如下的TSS結(jié)構(gòu)類(lèi)型:
;----------------------------------------------------------------------------;任務(wù)狀態(tài)段結(jié)構(gòu)類(lèi)型定義;----------------------------------------------------------------------------TSS STRUCTRLink DW 0 ;鏈接字段 DW 0 ;不使用,置為0TRESP0 DD 0 ;0級(jí)堆棧指針TRSS0 DW 0 ;0級(jí)堆棧段寄存器 DW 0 ;不使用,置為0TRESP1 DD 0 ;1級(jí)堆棧指針TRSS1 DW 0 ;1級(jí)堆棧段寄存器 DW 0 ;不使用,置為0TRESP2 DD 0 ;2級(jí)堆棧指針TRSS2 DW 0 ;2級(jí)堆棧段寄存器 DW 0 ;不使用,置為0TRCR3 DD 0 ;CR3TREIP DD 0 ;EIPTREFlag DD 0 ;EFLAGSTREAX DD 0 ;EAXTRECX DD 0 ;ECXTREDX DD 0 ;EDXTREBX DD 0 ;EBXTRESP DD 0 ;ESPTREBP DD 0 ;EBPTRESI DD 0 ;ESITREDI DD 0 ;EDITRES DW 0 ;ES DW 0 ;不使用,置為0TRCS DW 0 ;CS DW 0 ;不使用,置為0TRSS DW 0 ;SS DW 0 ;不使用,置為0TRDS DW 0 ;DS DW 0 ;不使用,置為0TRFS DW 0 ;FS DW 0 ;不使用,置為0TRGS DW 0 ;GS DW 0 ;不使用,置為0TRLDTR DW 0 ;LDTR DW 0 ;不使用,置為0TRTrip DW 0 ;調(diào)試陷阱標(biāo)志(只用位0)TRIOMap DW $+2 ;指向I/O許可位圖區(qū)的段內(nèi)偏移TSS ENDS