|
主要介紹段描述符,段選擇子
在保護(hù)模式下,段是實(shí)現(xiàn)虛擬地址到線性地址轉(zhuǎn)換的基礎(chǔ)。在保護(hù)方下,每個(gè)段有三個(gè)參數(shù):段基址,段界限,段屬性。段基址規(guī)定了線性地址空間中段的開始地址,段基址長度為32位,所以任何一個(gè)段都可以從32位線性地址空間中的任何一個(gè)字節(jié)開始,這一點(diǎn)和實(shí)式方式不同,實(shí)式方式下要求段的邊界必須被16整除。段界限規(guī)定段的大小,段界限用20位表示,而且段界限可以是字節(jié)或4K為單位,這個(gè)稱為段的粒度。當(dāng)段界限以字節(jié)為單位時(shí),那么段的范圍是1字節(jié)至1M字節(jié);當(dāng)段界限是以4K字節(jié)為單位時(shí),那么段的范圍是4K至4G。段的界限同時(shí)也是用來校驗(yàn)偏移地址的合法性,比如說段A的基址為00123456H,段界限為1000H,如果段界限以字節(jié)為單位,那么段的范圍是00123456H-00124456H;如果段界限以4K字節(jié)為單位,那么段的范圍是00123456H-00223456H。事實(shí)上,段的界限也可以用來校驗(yàn)偏移地址的合法性,上面的例子中界限為1000H,那么偏移地址的范圍就是0-1000H,如果偏移地址不在這個(gè)范圍內(nèi)那就會(huì)引起異常。需要說明的是,數(shù)據(jù)段有點(diǎn)特殊,因?yàn)閿?shù)據(jù)段的偏移范圍不僅僅是由段界限來決定,還要由段的擴(kuò)展方向(Extension Direction)來決定,因?yàn)橐疹櫟蕉褩6?堆棧段是一種特殊的數(shù)據(jù)段,它是向低端地址擴(kuò)展的),如果段界限為Limit,段的擴(kuò)展方向?yàn)橄蚋叨说刂窋U(kuò)展的話,那么我們可以斷定它是一普通的數(shù)據(jù)段,0-Limit是有效的偏移范圍,而Limit以上屬于無效的偏移范圍;如果段界限為Limit,段的擴(kuò)展方向?yàn)橄虻投说刂窋U(kuò)展的話,那么可以斷定它是一堆棧段,此時(shí)0-Limit是無效的偏移范圍,Limit以上則屬于有效的偏移范圍,正好和向高端地址擴(kuò)展的普通數(shù)據(jù)段相反。除了堆棧段以外,其它的段均是自然向高端擴(kuò)展。 段基址,段界限及段屬性這三個(gè)參數(shù)在保護(hù)模式下用描述符來描述,每個(gè)描述符的長度為8個(gè)字節(jié),每個(gè)段都有一個(gè)對(duì)應(yīng)的描述符。在保護(hù)模式下有三種描述符:存儲(chǔ)段描述符,系統(tǒng)段描述符,門描述符。 A.存儲(chǔ)段描述符:存儲(chǔ)段是指程序直接執(zhí)行的代碼段和數(shù)據(jù)段,存儲(chǔ)段描述符是用來描述存儲(chǔ)段的,也可以說是用來描述代碼和數(shù)據(jù)段的,它的長度為8個(gè)字節(jié),該描述符結(jié)構(gòu)示意圖: 第7字節(jié) 第6字節(jié) 第5字節(jié) 第4字節(jié) 第3字節(jié) 第2字節(jié) 第1字節(jié) 第0字節(jié) |--------|------------------|-----------------------------|-----------------| |段基址的| | | | |高8位 |Segment Attributes| 段基址的低24位 | 段界限的低16位 | | 24~31 | 段屬性,占用兩 | 0~23 | 0~15 | | | 個(gè)字節(jié) | | | |--------|------------------|-----------------------------|-----------------| | | | | _________| |_____________________________ | 15 14 13 12 11 8 7 6 5 3 0| |---|---|---|---|-------------|---|--- -|---|------------| | G | D |0 |AVL|段界限的高4位| P | DPL |DT | TYPE | |---|---|---|---|--- ---------|---|-----|---|------------| 段基址和段界限都被安排在描述符的兩個(gè)域中,主要是來看段的屬性: a.G(第15位),這是段界限粒度,即是說段界限到底是以字節(jié)為單還是以4K字節(jié)為單位。G=0表示段界限是字節(jié),G=1表示段界限為4K字節(jié)。 b.D(第14位),D是一個(gè)很特殊的位,在描述可執(zhí)行段,向低擴(kuò)展數(shù)據(jù)段或者由SS寄存器尋址的段。在描述可執(zhí)行段的描述符中,D位決定了指令使用的地址及操作數(shù)據(jù)默認(rèn)的大小,D=1表示默認(rèn)情況下使用32位地址及32位或8位操作數(shù),這樣的代碼段稱為32位代碼段;D=0表示默認(rèn)情況下使用16位地址及16位操作數(shù)或8位操作數(shù),這樣的代碼段稱為16位代碼段;在向低擴(kuò)展的數(shù)據(jù)段中,D=1表示段的上部界限為4G,D=0表示段的上部界限為64K;在描述由SS寄存器尋址的段中,該位決定使用隱式的堆棧訪問指令使用何種堆棧指針寄存器。D=1表示使用32位堆棧指針寄存器ESP,D=0表示使用16位堆棧指針寄存器SP,隱式的堆棧訪問指令指的是那些指令中沒有明顯對(duì)SP或ESP進(jìn)行操作的指令,比如說PUSH,POP,PUSHA,POPA,PUSHAD,POPAD都屬于隱式的堆棧訪問指令。 c.0(第13位),這一位恒為0,為80386以后的處理器保留的。 d.AVL(第12位),軟件可利用位,主要是為了保持和以后的處理兼容。 e.第11位到第8位是段界限的高4位。 f.P(第7位),存在位,P=1表示描述符對(duì)轉(zhuǎn)換地址有效。P=0表示描述符對(duì)轉(zhuǎn)換地址無效,如果使用該描述符將會(huì)引起異常。 g.DPL(Descriptor Privelege Level)描述符特權(quán)級(jí),共2位,它規(guī)定了所述段的特權(quán)級(jí)別,用于特權(quán)檢查,以決定是否能對(duì)該段進(jìn)行訪問。 h.DT(Descriptor Type)描述符的類型,DT=0表示存儲(chǔ)段描述符,DT=0表示系統(tǒng)段描述符和門描述符。 i.TYPE,共4位,說明存儲(chǔ)段的具體屬性: TYPE0:指示描述符是否被訪問,用A標(biāo)記,A=0表示描述符未被訪問,A=1表示描述符已被訪問。 TYPE1:根據(jù)TYPE3來確定。 TYPE2:根據(jù)TYPE3來確定。 TYPE3:指示描述符所描述的段是數(shù)據(jù)段還是代碼段,用E標(biāo)記。E=0表示是不可執(zhí)行段,是數(shù)據(jù)段,對(duì)應(yīng)的描述符也就是數(shù)據(jù)段描述符。E=1表示是可執(zhí)行段,也就是代碼段,對(duì)就的描述符也就是代碼段描述符。 如果TYPE3=0,也就是說描述符是數(shù)據(jù)段描述符,那么TYPE1指示該數(shù)據(jù)段是否可寫,用W標(biāo)記。W=0表示對(duì)應(yīng)的數(shù)據(jù)段不可寫,只讀。W=1表示對(duì)應(yīng)的數(shù)據(jù)段可寫。TYPE2則指示數(shù)據(jù)段的擴(kuò)展方向,用ED標(biāo)記。ED=0表示向高端擴(kuò)展,ED=1表示向低端擴(kuò)展。 如果TYPE3=1,也就是說描述符是代碼段描述符,那么TYPE1指示該代碼段是否可讀,用符號(hào)R標(biāo)記。R=0表示對(duì)應(yīng)的代碼段不可讀,只能執(zhí)行,R=1表示對(duì)應(yīng)的代碼可讀可執(zhí)行。TYPE2則指示所描述的代碼段是否是一致代碼段,用C表示。C=0表示代碼段不是一致代碼段,C=1表示是一致代碼段。 TYPE3-TYPE0這四位可以列成一個(gè)表: ___________________________________________________________________________________ |0000 |只讀 | |_____|____________________________________________________________________________| |0001 |只讀,已訪問 | |_____|____________________________________________________________________________| |0010 |可讀,可寫 | |_____|____________________________________________________________________________| |0011 |讀寫,已訪問 | |_____|____________________________________________________________________________| |0100 |只讀,向低擴(kuò)展 | |_____|____________________________________________________________________________| |0101 |只讀,向低擴(kuò)展 | |_____|____________________________________________________________________________| |0110 |讀/寫,向低擴(kuò)展 | |_____|____________________________________________________________________________| |0111 |讀/寫,向低擴(kuò)展,已訪問 | |_____|____________________________________________________________________________| |1000 |只執(zhí)行 | |_____|____________________________________________________________________________| |1001 |只執(zhí)行,已訪問 | |_____|____________________________________________________________________________| |1010 |可執(zhí)行,可讀 | |_____|____________________________________________________________________________| |1011 |可執(zhí)行,可讀,已訪問 | |_____|____________________________________________________________________________| |1100 |只執(zhí)行,一致代碼段 | |_____|____________________________________________________________________________| |1101 |只執(zhí)行,一致代碼段,已訪問 | |_____|____________________________________________________________________________| |1110 |可執(zhí)行,可讀,一致代碼段 | |_____|____________________________________________________________________________| |1111 |可執(zhí)行,可讀,一致代碼段,已訪問 | |_____|____________________________________________________________________________| 存儲(chǔ)段描述符的結(jié)構(gòu)可以這樣定義: DESCRIPTOR STRUCT Segment_LimitL16 DW 0;段界限的低16位 Segment_BaseL16 DW 0;段基址的低16位 Segment_BaseM8 DB 0;段基址的中間8位 Segment_BaseH8 DB 0;段基址的高8位 Segment_Attributes DW 0;段屬性 DESCRIPTOR ENDS 一個(gè)任務(wù)有多個(gè)段,每個(gè)段都有一個(gè)描述符。因此在80386下,為了方便管理這些段描述符,將描述符組成一個(gè)線性表,稱之為描述符表。在80386下有三種描述符表:GDT(Global Descriptor Table),LDT(Local Descriptor Table),IDT(Interrupt Descriptor Table)。在整個(gè)系統(tǒng)中全局描述符表GDT和中斷描述符表只有一張,局部描述符表可以由若干張。每個(gè)描述符表都形成一個(gè)特殊的16位數(shù)據(jù)段,這樣的特殊數(shù)據(jù)段最多可以有8192個(gè)描述符,具體使用哪一個(gè)段描述符,由段的選擇子來確定。每個(gè)任務(wù)都有自已的局部描述符表LDT,它包含自已的代碼段,數(shù)據(jù)段,堆棧段,也包含該任務(wù)使用的一些門描述符。隨著任務(wù)的切換,LDT也跟著切換。GDT包含每一個(gè)任務(wù)都可能或可以訪問的段的描述符,通常包含描述操作系統(tǒng)所用的代碼段,數(shù)據(jù)段以及堆棧段的描述符,也包含描述任務(wù)LDT的描述符。在任務(wù)切換時(shí),并不切換GDT。一個(gè)任務(wù)的整個(gè)虛擬地址空間可以分為相等的兩半,一半空間的描述符在全局描述符表GDT中,一半空的描述符在局部描述符表LDT中。由于全局描述符表和局部描述符表都可以包含最多為8192個(gè)描述符,而每個(gè)描述符所描述的段的最大長度為4G,因此最大的虛擬地址空間為:8192*4G*2=64TB。 段選擇子用來確定使用描述符表中的哪一個(gè)描述符。實(shí)式模式下邏輯地址由段地址*16再加上段內(nèi)偏移地址;保護(hù)模式下虛擬地址空間由段選擇子和段內(nèi)偏移來確定,和實(shí)式模式比較,段選擇子代替了段值,實(shí)際上通過段選擇子就可以確定了段基址。選擇子的高13位是描述符表中的索引號(hào),用來確定描述符,因?yàn)槭?3位,所以說最多可以有2的13次方8192個(gè)描述符,索引號(hào):0-8191。標(biāo)記TI指示是從全局描述符中讀取描述符還是從局部描述符表中讀取描述符。TI=0指示是從全局描述符表中讀取描述符,TI=1指示從局部描述符表讀取描述符。RPL表示請(qǐng)求特權(quán)級(jí),用于特權(quán)檢查。假設(shè)段選擇子為88H,則表示請(qǐng)求的特權(quán)級(jí)別是0,從全局描述表中讀取描述表,描述符的索引號(hào)為11H。有一個(gè)特殊的選擇子稱為空選擇子,它的Index=0(即高13位為0),TI=0,RPL則可以為任意值。當(dāng)用空選擇子對(duì)存儲(chǔ)器進(jìn)行訪問,會(huì)出現(xiàn)異常??者x擇子對(duì)應(yīng)于全局描述表中的第0個(gè)描述符,因此全局描述符表中的第0個(gè)描述符總是不會(huì)被訪問。如果TI=1,那么就不是空選擇子,它指定的是當(dāng)前局部描述符表中的第0個(gè)描述符。為了更快地從段選擇子中獲得段的基本信息(段基址,段界限,段屬性),從80386開始為每個(gè)段寄存器在硬件上配備了段描述符高速緩沖存儲(chǔ)器,對(duì)我們寫程序的人來講,它是不可編程的。有了這種高速緩沖寄存器后,每當(dāng)將選擇子裝入段寄存器后,處理器將自動(dòng)裝入描述符表中相應(yīng)的描述符,并將描述表的信息裝入到高速緩沖寄存器,這樣可以加快訪問速度,以下是段選擇子的結(jié)構(gòu)示意圖: 15________________________________________________________________3__2__1_____0 | |TI | RPL | |________________________________________________________________|___|________| |
|
|