首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

保護模式分段管理機制深度解析:描述符、選擇子與地址轉換

     編輯:組合語言

80386 保護模式的核心在於分段管理機制。本文系統闡述段定義參數、描述符結構、GDT/LDT 組織、選擇子格式、描述符快取寄存器,以及虛擬地址到線性地址的完整轉換流程。

一、段定義三參數與虛擬→線性地址轉換

每個段由三參數定義:

  • 基地址 (32-bit):段在 4GB 線性空間起始位址,任意位元組對齊
  • 界限 (20-bit):段大小。粒度位 G 決定單位:
    • G=0:位元組粒度,1B~1MB
    • G=1:4KB 頁粒度,4KB~4GB,實際界限 LIMIT = (Limit << 12) + 0FFFH
  • 屬性:類型、特權級 (DPL)、存在位 (P)、擴展方向 (ED, 僅資料段)、預設大小 (D) 等

地址轉換:線性地址 = 基地址 + 段內偏移。偏移必須在有效範圍內,否則觸發異常 (GP/SS)。

擴展方向 (ED):

  • ED=0 (向上擴展):偏移 0~Limit 有效,基地址→基地址+Limit
  • ED=1 (向下擴展,堆疊段):**偏移 Limit+1 ~ 最大值有效**,基地址為高端,向低位擴展

二、段描述符結構 (8 位元組)

Byte 7   6   5   4   3   2   1   0
+-------+---+---+---+---+---+---+---+
| Base31-24 | G | D | 0 |AVL|Lim19-16| P | DPL |1| TYPE | Base23-16 | Base15-0 | Lim15-0 |
+-------+---+---+---+---+---+---+---+

關鍵欄位:

欄位位置說明
Base0-15, 16-23, 24-3132-bit 基地址,分三段存放
Limit0-15, 16-1920-bit 界限,分兩段存放
PByte 5, bit 7存在位:1=在記憶體, 0=不在 (觸發 #NP)
DPLByte 5, bit 5-6描述符特權級 (0-3)
DT (S)Byte 5, bit 41=儲存段描述符 (代碼/資料), 0=系統段/門
TYPEByte 5, bit 0-3段具體屬性 (見下表)
GByte 6, bit 7界限粒度
DByte 6, bit 6預設大小:代碼段=32/16-bit;堆疊段=ESP/SP;向下擴展段上界 4GB/64KB
AVLByte 6, bit 4軟體可用位,處理器忽略

TYPE 欄位詳細編碼

資料段 (E=0)代碼段 (E=1)
值屬性值屬性
0唯讀8唯執行
1唯讀, 已存取9唯執行, 已存取
2讀/寫A執行/讀
3讀/寫, 已存取B執行/讀, 已存取
4唯讀, 向下擴展C唯執行, 一致碼段
5唯讀, 向下擴展, 已存取D唯執行, 一致, 已存取
6讀/寫, 向下擴展E執行/讀, 一致
7讀/寫, 向下擴展, 已存取F執行/讀, 一致, 已存取

已存取位 (A, TYPE bit 0):處理器載入選擇子到段寄存器時自動置 1,OS 可掃描判斷段使用情況。

一致碼段 (C, TYPE bit 2):允許低特權程式以當前 CPL 執行高特權代碼 (不改變 CPL),用於共用庫。

三、描述符表:GDT / LDT / IDT

  • GDT:系統唯一,含 OS 核心段、TSS、LDT 描述符、共用段。任務切換不切換 GDT。
  • LDT:每任務可擁有一個,含任務私有代碼/資料/堆疊/門描述符。任務切換時切換 LDTR。
  • IDT:系統唯一,含 256 條門描述符 (中斷/陷阱/任務門)。

每表最多 8192 條描述符 (13-bit 索引 × 8 bytes = 64KB)。虛擬空間 = 4GB × 8192 × 2 (GDT+LDT) = 64TB。

四、段選擇子 (16-bit)

15                    3 2 1 0
+----------------------+-+-+-+
|      Index (13)      |T|RPL|
+----------------------+-+-+-+
  • Index:描述符在表中索引 (0~8191)
  • TI (Table Indicator):0=GDT, 1=LDT
  • RPL (Requested Privilege Level):請求特權級,用於特權檢查。實際比較用 max(CPL, RPL) vs DPL

空選擇子:Index=0, TI=0, RPL=任意。載入資料段寄存器不報錯,但後續存取觸發 #GP。GDT[0] 永遠不被使用,通常全 0。

五、段描述符快取寄存器 (描述符投影寄存器)

每個段寄存器 (CS/SS/DS/ES/FS/GS) 內建不可見快取,載入選擇子時自動從描述符表讀取描述符資訊 (基地址、界限、屬性) 存入快取。後續存取直接用快取,**不再查表**。

快取內容:32-bit 基地址、32-bit 界限 (已按 G 展開)、P、DPL、A、G、ED、R、W、X、D/B (堆疊大小)、C (一致)。

關鍵含義:修改記憶體中描述符後,**必須重新載入段寄存器** 更新快取,否則舊屬性繼續生效。

總結:虛擬地址→線性地址完整流程

  1. 程式給出 Selector:Offset
  2. 若選擇子 ≠ 段寄存器當前值 → 載入段寄存器 → 硬體自動:
    • 依 TI 選 GDT/LDT
    • 依 Index 取描述符
    • 特權檢查 (max(CPL,RPL) ≤ DPL, P=1, 類型匹配)
    • 載入快取 (Base, Limit, Attributes)
  3. 檢查 Offset ≤ Limit (向上) 或 Offset > Limit (向下)
  4. 線性地址 = Base + Offset
  5. 若開啟分頁 → 線性地址 → 物理地址 (另文說明)

此機制提供了硬體層面的記憶體保護、特權隔離、虛擬記憶體基礎,是現代作業系統核心架構的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved