## 5.1 分段地址轉換(Segment Translation)
圖5-2詳細顯示了處理器如何把邏輯地址轉換為線性地址。
為了這樣的轉換,處理器用到了以下的數據結構:
1、 描述符(Descriptors)
2、 描述符表(Descriptor tables)
3、 選擇子(Selectors)
4、 段寄存器(Segment Registers)
### 5.1.1 描述符(Descriptors)
段描述符是處理器用來把邏輯地址映射為線性地址的必要數據結構。描述符是由編譯器、連接器、加載器、或者是操作系統生成的,不能由應用程序員生成。圖5-3顯示了兩種常用的描述符的格式。所有的段描述符都是這兩種格式當中的一種。段描述符的字段是以下:
基址(BASE):決定了一個段在4G線性地址空間中的位置。處理器把3部分基址聯接在一起,來形成一個32位的基址。
界限(LIMIT):決定了一個段的大小。處理器用2部分的界限字段來形成一個20位的界限值。處理器以兩種方式來解析界限的值,解析方式取決于粒度位的設置情況:
1、? 當單元大小為一個字節時,則定義了一個最大為1M字節的段。
2、? 如果單元大小為4K字節,則段大小可以高達4G。界限值在使用之前處理器將會把它先左移12位,低12位則自動插入0。
粒度位(Granularity bit):決定了界限值被處理器解析的方式。當它被復位時,界限值被解析為以1字節為一個單元。當它置位時,則界限值以4K為一個單元。
類型(TYPE):用于區別不同類型的描述符。
描述符特權級(Descriptor Privilege Level)(DPL):用來實現保護機制(參看第六章)。
段存在位(Segment-Present bit):如果這一位為0,則此描述符為非法的,不能被用來實現地址轉換。如果一個非法描述符被加載進一個段寄存器,處理器會立即產生異常。圖5-4顯示了當存在位為0時,描述符的格式。操作系統可以任意的使用被標識為可用(AVAILABLE)的位。一個實現基于段的虛擬內存的操作系統可以在以下情況下來清除存在位:
1、? 當這個段的線性地址空間并沒有完全被分頁系統映射到物理地址空間時。
2、? 當段根本沒有在內存里時。
已訪問位(Accessed bit):當處理器訪問該段時,將自動設置訪問位。也就是說,當一個指向該段描述符的選擇子被加載進一個段寄存器時或者當被一條選擇子測試指令使用時。在段級基礎上實現虛擬內存的操作系統可能會周期性的測試和清除該位,從而監視一個段的使用情況。
創建和維擬描述符是系統軟件的任務,一般說來可能是由,編譯器、程序加載器、系統生成器、或者操作系統來協作完成的。


### 5.1.2 描述符表(Descriptor Tables)
段描述符存儲在以下兩種描述符表當中的一個:
1、 全局描述符表(GDT)
2、 一個局部描述符表(LDT)
就象圖5-5所示的一樣,一個描述符表僅僅是一個包含了很多描述符的8字節內存數組而以。描述符表是長度是可變的,最多可包含高達8192(2^13)個描述符。便是處理器是不會使用全局描述符表的第一項(INDEX=0)的。
處理器用GDTR和LDTR來定位內存中的全局描述符表和當前的局部描述符表。這些寄存器存儲了這些表的線性地址的基址和段長界限。指令LGDT和SGDT是用業訪問全局描述符表寄存器的,而指令LLDT和SLDT則是用來訪問局部描述符表寄存器的。


### 5.1.3 選擇子(Selectors)
線性地址部分的選擇子是用來選擇哪個描述符表和在該表中索引一個描述符的。選擇子可以做為指針變量的一部分,從而對應用程序員是可見的,但是一般是由連接加載器來設置的。圖5-6顯示了選擇子的格式。
索引(Index):在描述符表中從8192個描述符中選擇一個描述符。處理器自動將這個索引值乘以8(描述符的長度),再加上描述符表的基址來索引描述符表,從而選出一個合適的描述符。
表指示位(Table Indicator):選擇應該訪問哪一個描述符表。0代表應該訪問全局描述符表(GDT),1代表應該訪問局部描述符表。
請求特權級(Requested Privilege Level):保護機制使用該位(參看第六章)。
由于全局描述符表的第一項是不被處理器使用的,所以當一個選擇子的索引(Index)部分和表指示位(Table Indicator)都為0的時候(也就是說,選擇子指向全局描述符表的第一項時),可以當做一個空的選擇子。當一個段寄存器被加載一個空選擇子時,處理器并不會產生一個異常。但是,當用一個空選擇子去訪問內存時,則會產生異常。這個特點可以用來初始化不用的段寄存器,以防偶然性的非法訪問。


### 5.1.4 段寄存器(Segment Registers)
80386把描述符的信息存儲在段寄存器里,以便不用每次內存訪問都去訪問內存中的描述符表。
如圖5-7所示,每一個段寄存器都有一個可見部分和一個不可見部分。這些段寄存器的可見部分被程序員當作一個16位的寄存器來使用。不可見的部分則只能由處理器來操縱。
加載這些寄存器的操作和一般的加載指令是一樣的(和第三章講述的相同),這些指令分為兩類:
1、? 真接的加載指令,例如,MOV,POP,LDS,LSS,LGS,LFS。這些指令顯示的訪問這些段寄存器。
2、? 隱式的加載指令,例如,far CALL和JMP。這些指令隱式的訪問CS 段寄存器,將它加載一個新的值。
使用這些指令,程序將用一個16位的選擇子加載段寄存器的可見部分。處理器將自動的將基址、界限、類型、和其它信息從描述符表中加載到段選擇子的不可見部分。
因為很多數據訪問的指令都是訪問一個已加載段寄存器的數據段,所以處理器可以用與段相關的基址部分加上指令提供的偏移部分,而且不會有額處的加法開銷。
- 第一章 80386介紹
- 1.1 該手冊的組織結構
- 1.2 其他文獻
- 第二章 編程基本模型
- 2.1 存儲器組織和段
- 2.2 數據類型
- 2.3 寄存器
- 2.4 指令格式
- 2.5 操作數選擇
- 2.6 中斷和異常
- 第4章 系統寄存器
- 4.1 系統寄存器 (System Registers)
- 4.2 系統指令 (System Instructions)
- 第五章 內存管理
- 5.1 分段地址轉換(Segment Translation)
- 5.2 分頁地址轉換(Page Translation)
- 5.3 混合分段和分頁地址轉換(Combining Segment and Page Translation)
- 第六章 內存管理
- 6.1 為什么要保護(Why Protection?)
- 6.2 80386保護機制概述(Overview of 80386 Protection Mechnaisms)
- 6.3 段級保護(Segment-Level Protection)
- 6.4 頁級保護(Page-Level Protection)
- 6.5 混合分頁和分段保護(Combining Page and Segment Protection)
- 第7章 多任務(Multitasking)
- 8.1 I/O 尋址(I/O Addressing)
- 7.1 任務狀態段(Task State Segment)
- 7.3 任務寄存器(Task Register)
- 7.4 任務門描述符(Task Gate Descriptor)
- 7.5 任務切換(Task Switching)
- 7.6 任務鏈(Task Linking)
- 7.7 任務尋址空間(Task Address Space)
- 第8章 輸入 輸出
- 8.2 I/O 指令(I/O Instructions)
- 8.3 保護和I/O(Protection and I/O)
- 第9章 異常和中斷(Exceptions and Interrupts)
- 9.1 識別中斷(Identifying Interrupts)
- 9.2 允許和禁止中斷(Enabling and Disabling Interrupts)
- 9.3 同時發生的中斷和異常的優先級(Priority Among Simultaneous Interrupts and Exceptions)
- 9.4 中斷描述符表(Interrupt Descriptor Table)
- 9.5 IDT 描述符(IDT Descriptors)
- 9.6 中斷任務和中斷子程序(Interrupt Tasks and Interrupt Procedures)
- 9.7 出錯碼(Error Code)
- 9.8 異常條件(Exception Conditions)
- 9.9 異常總結(Exception Summary)
- 9.10 出錯碼總結(Error Code Summary)
- 第10章 初始化(Initialization)
- 10.1 復位后處理器狀態(Processor State After Reset)
- 10.2 實模式初始化(Software Initialization for Real-Address Mode)
- 10.3 切換到保護模式(Switching to Protected Mode)
- 10.4 保護模式初始化(Software Initialization for Protected Mode)
- 10.5 初始化示例
- 10.6 TLB測試
- 第十四章 80386實地址模式
- 14.1 物理地址構成
- 14.2 寄存器和指令
- 14.3 中斷和異常處理
- 14.4 進入和離開實地址模式
- 14.6 實地址模式異常
- 14.7 與8086的不同
- 14.8 與80286實地址模式的不同