?? 匯編006.txt
字號:
主要介紹段描述符,段選擇子
在保護模式下,段是實現虛擬地址到線性地址轉換的基礎。在保護方下,每個段有三個參數:段基址,段界限,段屬性。段基址規定了線性地址空間中段的開始地址,段基址長度為32位,所以任何一個段都可以從32位線性地址空間中的任何一個字節開始,這一點和實式方式不同,實式方式下要求段的邊界必須被16整除。段界限規定段的大小,段界限用20位表示,而且段界限可以是字節或4K為單位,這個稱為段的粒度。當段界限以字節為單位時,那么段的范圍是1字節至1M字節;當段界限是以4K字節為單位時,那么段的范圍是4K至4G。段的界限同時也是用來校驗偏移地址的合法性,比如說段A的基址為00123456H,段界限為1000H,如果段界限以字節為單位,那么段的范圍是00123456H-00124456H;如果段界限以4K字節為單位,那么段的范圍是00123456H-00223456H。事實上,段的界限也可以用來校驗偏移地址的合法性,上面的例子中界限為1000H,那么偏移地址的范圍就是0-1000H,如果偏移地址不在這個范圍內那就會引起異常。需要說明的是,數據段有點特殊,因為數據段的偏移范圍不僅僅是由段界限來決定,還要由段的擴展方向(Extension Direction)來決定,因為要照顧到堆棧段(堆棧段是一種特殊的數據段,它是向低端地址擴展的),如果段界限為Limit,段的擴展方向為向高端地址擴展的話,那么我們可以斷定它是一普通的數據段,0-Limit是有效的偏移范圍,而Limit以上屬于無效的偏移范圍;如果段界限為Limit,段的擴展方向為向低端地址擴展的話,那么可以斷定它是一堆棧段,此時0-Limit是無效的偏移范圍,Limit以上則屬于有效的偏移范圍,正好和向高端地址擴展的普通數據段相反。除了堆棧段以外,其它的段均是自然向高端擴展。
段基址,段界限及段屬性這三個參數在保護模式下用描述符來描述,每個描述符的長度為8個字節,每個段都有一個對應的描述符。在保護模式下有三種描述符:存儲段描述符,系統段描述符,門描述符。
A.存儲段描述符:存儲段是指程序直接執行的代碼段和數據段,存儲段描述符是用來描述存儲段的,也可以說是用來描述代碼和數據段的,它的長度為8個字節,該描述符結構示意圖:
第7字節 第6字節 第5字節 第4字節 第3字節 第2字節 第1字節 第0字節
|--------|------------------|-----------------------------|-----------------|
|段基址的| | | |
|高8位 |Segment Attributes| 段基址的低24位 | 段界限的低16位 |
| 24~31 | 段屬性,占用兩 | 0~23 | 0~15 |
| | 個字節 | | |
|--------|------------------|-----------------------------|-----------------|
| |
| |
_________| |_____________________________
| 15 14 13 12 11 8 7 6 5 3 0|
|---|---|---|---|-------------|---|--- -|---|------------|
| G | D |0 |AVL|段界限的高4位| P | DPL |DT | TYPE |
|---|---|---|---|--- ---------|---|-----|---|------------|
段基址和段界限都被安排在描述符的兩個域中,主要是來看段的屬性:
a.G(第15位),這是段界限粒度,即是說段界限到底是以字節為單還是以4K字節為單位。G=0表示段界限是字節,G=1表示段界限為4K字節。
b.D(第14位),D是一個很特殊的位,在描述可執行段,向低擴展數據段或者由SS寄存器尋址的段。在描述可執行段的描述符中,D位決定了指令使用的地址及操作數據默認的大小,D=1表示默認情況下使用32位地址及32位或8位操作數,這樣的代碼段稱為32位代碼段;D=0表示默認情況下使用16位地址及16位操作數或8位操作數,這樣的代碼段稱為16位代碼段;在向低擴展的數據段中,D=1表示段的上部界限為4G,D=0表示段的上部界限為64K;在描述由SS寄存器尋址的段中,該位決定使用隱式的堆棧訪問指令使用何種堆棧指針寄存器。D=1表示使用32位堆棧指針寄存器ESP,D=0表示使用16位堆棧指針寄存器SP,隱式的堆棧訪問指令指的是那些指令中沒有明顯對SP或ESP進行操作的指令,比如說PUSH,POP,PUSHA,POPA,PUSHAD,POPAD都屬于隱式的堆棧訪問指令。
c.0(第13位),這一位恒為0,為80386以后的處理器保留的。
d.AVL(第12位),軟件可利用位,主要是為了保持和以后的處理兼容。
e.第11位到第8位是段界限的高4位。
f.P(第7位),存在位,P=1表示描述符對轉換地址有效。P=0表示描述符對轉換地址無效,如果使用該描述符將會引起異常。
g.DPL(Descriptor Privelege Level)描述符特權級,共2位,它規定了所述段的特權級別,用于特權檢查,以決定是否能對該段進行訪問。
h.DT(Descriptor Type)描述符的類型,DT=0表示存儲段描述符,DT=0表示系統段描述符和門描述符。
i.TYPE,共4位,說明存儲段的具體屬性:
TYPE0:指示描述符是否被訪問,用A標記,A=0表示描述符未被訪問,A=1表示描述符已被訪問。
TYPE1:根據TYPE3來確定。
TYPE2:根據TYPE3來確定。
TYPE3:指示描述符所描述的段是數據段還是代碼段,用E標記。E=0表示是不可執行段,是數據段,對應的描述符也就是數據段描述符。E=1表示是可執行段,也就是代碼段,對就的描述符也就是代碼段描述符。
如果TYPE3=0,也就是說描述符是數據段描述符,那么TYPE1指示該數據段是否可寫,用W標記。W=0表示對應的數據段不可寫,只讀。W=1表示對應的數據段可寫。TYPE2則指示數據段的擴展方向,用ED標記。ED=0表示向高端擴展,ED=1表示向低端擴展。
如果TYPE3=1,也就是說描述符是代碼段描述符,那么TYPE1指示該代碼段是否可讀,用符號R標記。R=0表示對應的代碼段不可讀,只能執行,R=1表示對應的代碼可讀可執行。TYPE2則指示所描述的代碼段是否是一致代碼段,用C表示。C=0表示代碼段不是一致代碼段,C=1表示是一致代碼段。
TYPE3-TYPE0這四位可以列成一個表:
___________________________________________________________________________________
|0000 |只讀 |
|_____|____________________________________________________________________________|
|0001 |只讀,已訪問 |
|_____|____________________________________________________________________________|
|0010 |可讀,可寫 |
|_____|____________________________________________________________________________|
|0011 |讀寫,已訪問 |
|_____|____________________________________________________________________________|
|0100 |只讀,向低擴展 |
|_____|____________________________________________________________________________|
|0101 |只讀,向低擴展 |
|_____|____________________________________________________________________________|
|0110 |讀/寫,向低擴展 |
|_____|____________________________________________________________________________|
|0111 |讀/寫,向低擴展,已訪問 |
|_____|____________________________________________________________________________|
|1000 |只執行 |
|_____|____________________________________________________________________________|
|1001 |只執行,已訪問 |
|_____|____________________________________________________________________________|
|1010 |可執行,可讀 |
|_____|____________________________________________________________________________|
|1011 |可執行,可讀,已訪問 |
|_____|____________________________________________________________________________|
|1100 |只執行,一致代碼段 |
|_____|____________________________________________________________________________|
|1101 |只執行,一致代碼段,已訪問 |
|_____|____________________________________________________________________________|
|1110 |可執行,可讀,一致代碼段 |
|_____|____________________________________________________________________________|
|1111 |可執行,可讀,一致代碼段,已訪問 |
|_____|____________________________________________________________________________|
存儲段描述符的結構可以這樣定義:
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
一個任務有多個段,每個段都有一個描述符。因此在80386下,為了方便管理這些段描述符,將描述符組成一個線性表,稱之為描述符表。在80386下有三種描述符表:GDT(Global Descriptor Table),LDT(Local Descriptor Table),IDT(Interrupt Descriptor Table)。在整個系統中全局描述符表GDT和中斷描述符表只有一張,局部描述符表可以由若干張。每個描述符表都形成一個特殊的16位數據段,這樣的特殊數據段最多可以有8192個描述符,具體使用哪一個段描述符,由段的選擇子來確定。每個任務都有自已的局部描述符表LDT,它包含自已的代碼段,數據段,堆棧段,也包含該任務使用的一些門描述符。隨著任務的切換,LDT也跟著切換。GDT包含每一個任務都可能或可以訪問的段的描述符,通常包含描述操作系統所用的代碼段,數據段以及堆棧段的描述符,也包含描述任務LDT的描述符。在任務切換時,并不切換GDT。一個任務的整個虛擬地址空間可以分為相等的兩半,一半空間的描述符在全局描述符表GDT中,一半空的描述符在局部描述符表LDT中。由于全局描述符表和局部描述符表都可以包含最多為8192個描述符,而每個描述符所描述的段的最大長度為4G,因此最大的虛擬地址空間為:8192*4G*2=64TB。
段選擇子用來確定使用描述符表中的哪一個描述符。實式模式下邏輯地址由段地址*16再加上段內偏移地址;保護模式下虛擬地址空間由段選擇子和段內偏移來確定,和實式模式比較,段選擇子代替了段值,實際上通過段選擇子就可以確定了段基址。選擇子的高13位是描述符表中的索引號,用來確定描述符,因為是13位,所以說最多可以有2的13次方8192個描述符,索引號:0-8191。標記TI指示是從全局描述符中讀取描述符還是從局部描述符表中讀取描述符。TI=0指示是從全局描述符表中讀取描述符,TI=1指示從局部描述符表讀取描述符。RPL表示請求特權級,用于特權檢查。假設段選擇子為88H,則表示請求的特權級別是0,從全局描述表中讀取描述表,描述符的索引號為11H。有一個特殊的選擇子稱為空選擇子,它的Index=0(即高13位為0),TI=0,RPL則可以為任意值。當用空選擇子對存儲器進行訪問,會出現異常??者x擇子對應于全局描述表中的第0個描述符,因此全局描述符表中的第0個描述符總是不會被訪問。如果TI=1,那么就不是空選擇子,它指定的是當前局部描述符表中的第0個描述符。為了更快地從段選擇子中獲得段的基本信息(段基址,段界限,段屬性),從80386開始為每個段寄存器在硬件上配備了段描述符高速緩沖存儲器,對我們寫程序的人來講,它是不可編程的。有了這種高速緩沖寄存器后,每當將選擇子裝入段寄存器后,處理器將自動裝入描述符表中相應的描述符,并將描述表的信息裝入到高速緩沖寄存器,這樣可以加快訪問速度,以下是段選擇子的結構示意圖:
15________________________________________________________________3__2__1_____0
| |TI | RPL |
|________________________________________________________________|___|________|
主要介紹系統地址寄存器和控制寄存器以及在程序中實方式下與保護方式下的切換
80386處理器新增了一組控制寄存器CR0,CR1,CR2,CR3和一組系統地址寄存器GDTR,LDTR,IDTR,TR,它們全部都是32位的。CR0包含了指定處理器工作方式的控制位,CR1保留未使用,CR2和CR3由分頁管理部件使用,CR0中的5~30位和CR3中的0~11位必須為0,分別介紹如下:
___________________________________________________________________________
|PG|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |ET|TS|EM|MP|PE| CR0
|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|_ |__|
| Reserved | CR1
|__________________________________________________________________________|
| 頁故障線性地址 | CR2
|__________________________________________________________________________|
| 高20位頁表的起始物理地址 |低12位為0 | CR3
|_____________________________________________________|____________________|
PE標記用于指定處理器的工作模式。PE=0,處理器處于實模式;PE=1,處理器處于保護模式
PG標記用于指定處理器是否啟用分頁管理機制。PG=0,禁用分頁管理機制,此時由分段管理部件產生的線性地址就是物理地址。;PG=1,啟用分頁管理機制,此時由分段管理部件產生的線性地址須再經過分頁管理機制才能得到最終的物理地址。
MP,EM,TS,ET用于控制浮點協處理器的操作。
CR2和CR3控制寄存器由分頁管理機制使用。CR2用于發生頁異常時報告出錯信息。當發生頁故障時,處理器會將當前的線性地址保存在CR2。CR3用于保存頁表在內存中的起始物理地址,由于頁表是對齊的,所以僅高20位有效,低12位必須為0。
全局描述符表GDT,局部描述符表LDT和中斷描述符表IDT在保護模式下是特殊的段,也就是說處理器將這些線性表當段一個特殊的段來處理,它包含了對段機制所用的重要數據。為了能夠更快速地進位這些段,386處理器采用特殊的寄存器保存這種段的基地址和界限,這種寄存器就是系統地址寄存。在80386下系統地址寄存器有:全局描述符表寄存器GDTR,局部描述符表寄存器LDTR,中斷描述符表IDTR,任務狀態段寄存器TR。全局描述符表寄存器GDTR,長度為48位,其中高32位是基址,低16位含界限。由于GDT本身不可以由GDT內的描述符來描述,所以處理使用GDTR寄存器為GDT這樣的特殊段提供一個偽描述符,即是說:
| |
|________________| 全局描述符表寄存器GDTR
| | ________________________________
| GDT |______| | |
|________________|______| 32位基址 | 16界限 |
| | |___________________|___________|
| |
因為段選擇子只用了13位來表描述表中的索引號,即是說最多可以有8192個描述符,而每個描述符是8個字節。而在80386處理器下將全局描述表作為一個特殊的系統段,那么段的界限實際上就是8192*8,所以段的界限用16位就可以了。通常情況下,如果GDT有N個描述符,那么GDT的段界限為N*8-1,這個偽描述符也就是全局描述符寄存器內容可以用結體定義成:
PreDesc STRUCT
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -