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

x86 保護模式核心架構:控制暫存器 (CR0-CR3) 與系統位址暫存器 (GDTR/IDTR/LDTR/TR) 完整解析

     編輯:組合語言

前言

80386 引入的保護模式架構,核心在於四組 32 位元控制暫存器 (CR0-CR3) 與四組系統位址暫存器 (GDTR, IDTR, LDTR, TR)。它們共同管控:模式切換、分頁機制、協處理器協調、描述符表定位、任務切換。本文完整解析每個暫存器的位定義、功能、程式設計介面與實務操作指南。

控制暫存器總覽

暫存器位範圍關鍵位主要功能
CR031..0PG(31), ET(4), TS(3), EM(2), MP(1), PE(0)模式控制、分頁啟用、協處理器管理
CR1-保留未來擴充,80386 讀寫觸發 #UD
CR231..0Page Fault Linear Address頁錯誤線性位址紀錄
CR331..12Page Directory Base (PDBR)頁目錄表物理基址 (低 12 位保留=0)

CR0 詳細位定義


CR0:
31  30-5   4   3   2   1   0
PG  0...0  ET  TS  EM  MP  PE

保護控制位

  • PE (Position 0):0=Real Mode, 1=Protected Mode。啟用分段保護機制。
  • PG (Position 31):0=Disable Paging, 1=Enable Paging。啟用分頁機制 (線性位址→物理位址轉換)。
  • 合法組合:
    PGPE模式
    00Real Mode
    01Protected Mode, 無分頁
    10非法 → #GP
    11Protected Mode + Paging
  • 修改 PG 要求:目前執行程式碼與至少部分資料在線性/物理位址空間同位址 (Identity Mapping),否則修改後立即失控。

協處理器控制位

  • MP (Math Present, bit 1):1 = 系統有數學協處理器 (80387)。影響 WAIT 指令行為。
  • EM (Emulation, bit 2):1 = 無協處理器,浮點指令觸發 #NM (Device Not Available) 由軟體模擬處理;0 = 硬體執行。
  • TS (Task Switched, bit 3):任務切換時由處理器自動置 1。TS=1 時,浮點指令觸發 #NM,讓 OS 決定是否儲存/恢復協處理器狀態 (Lazy Save/Restore)。
  • ET (Extension Type, bit 4):Reset 時由硬體設定。1=80387, 0=80287 或無。指示協處理器介面類型。
  • 互動邏輯:
    • WAIT:若 MP=1 且 TS=1 → #NM;MP=0 → 忽略 TS。
    • 浮點指令:若 EM=1 → #NM;EM=0 且 TS=1 → #NM (Lazy context switch)。

CR2: 頁錯誤線性位址

  • 發生 #PF (Page Fault, 中斷 14h) 時,處理器自動將導致錯誤的 線性位址 存入 CR2。
  • OS 頁錯誤處理常式讀取 CR2 判斷缺頁位址,決定:配置實體頁面、載入換頁檔、存取違例終止程序等。
  • 僅讀暫存器 (OS 不直接寫入)。

CR3: 頁目錄基址暫存器 (PDBR)

  • 位 31..12:頁目錄表物理頁框號 (PFN),即物理基址 / 4KB。
  • 位 11..0:保留,必須為 0 (頁目錄 4KB 對齊)。
  • 寫入 CR3 副作用:刷新 TLB (Translation Lookaside Buffer),清除所有分頁快取。用於:切換進程位址空間、啟用分頁前預先刷新。
  • 任務切換:TSS 中儲存 CR3,任務切換自動載入新 CR3。若新舊 CR3 相同 (共享頁目錄),處理器 不刷新 TLB,加速切換。
  • 可在 Real Mode / PE=0 時寫入,便於分頁初始化。

系統位址暫存器 (48-bit / 16-bit + 隱藏快取)

每個暫存器包含 可見部分 (程式設計師可讀寫) 與 隱藏快取部分 (處理器自動載入描述符內容)。

GDTR: 全域描述符表暫存器


GDTR (48-bit):
31-0: Base Linear Address (GDT 線性基址)
15-0: Limit (界限, 位元組為單位)
  • LGDT [mem] 載入,SGDT [mem] 存回。
  • 界限單位 = 位元組。典型值 = 8*N - 1 (N = 描述符數)。
  • GDT 本身無描述符描述,GDTR 視為「偽描述符」。

IDTR: 中斷描述符表暫存器

  • 結構同 GDTR (48-bit: Base + Limit)。
  • 支援 256 個中斷/異常 → 最大 2KB → 界限最大 7FFh。
  • LIDT / SIDT 載入/存回。

LDTR: 區域描述符表暫存器

  • 可見部分 (16-bit):LDT 描述符的選擇子 (Selector)。
  • 隱藏部分:LDT 基址、界限、屬性 (從 GDT 讀取描述符後載入)。
  • 載入流程:LLDT selector → 選擇子必指向 GDT 中 Type=LDT 的系統段描述符 (TI=0)。
  • 可載入空選擇子 (0) 表示當前任務無 LDT,所有段選擇子必指向 GDT。

TR: 任務狀態段暫存器

  • 可見部分 (16-bit):TSS 描述符選擇子。
  • 隱藏部分:TSS 基址、界限、屬性 (從 GDT 讀取)。
  • 必須指向 GDT 中 Type=TSS 的描述符,不可為空。
  • 任務切換時自動更新:儲存舊任務狀態到舊 TSS,載入新 TSS 選擇子到 TR,從新 TSS 恢復暫存器組。

程式設計介面 (MOV 到/從控制暫存器)


; 讀取 CR0
mov eax, cr0

; 寫入 CR0 (啟用保護模式)
mov eax, cr0
or eax, 1
mov cr0, eax

; 讀取 CR2 (頁錯誤處理常式)
mov eax, cr2

; 設定 CR3 (切換頁目錄)
mov cr3, eax    ; EAX = 新頁目錄物理基址 (低 12 位=0)

; 系統位址暫存器需用特定指令
lgdt fword ptr [gdtr_ptr]   ; GDTR
lidt fword ptr [idtr_ptr]   ; IDTR
lldt ax                     ; LDTR (AX=selector)
ltr ax                      ; TR (AX=selector)
sgdt fword ptr [gdtr_ptr]   ; 存回
sidt fword ptr [idtr_ptr]
sldt ax                     ; LDTR → AX
str ax                      ; TR → AX

偽描述符資料結構定義


PDESC STRUC
    LIMIT DW 0
    BASE  DD 0
PDESC ENDS

; 使用範例
gdtr_ptr PDESC 
lgdt fword ptr [gdtr_ptr]

實務操作指南與陷阱

操作關鍵點
啟用保護模式1. 建立 GDT/IDT 2. LGDT/LIDT 3. CR0.PE=1 4. 遠跳轉清空管線 (JMP FAR)
啟用分頁1. 建立頁目錄/頁表 (Identity Mapping 含目前代碼) 2. CR3=頁目錄基址 3. CR0.PG=1
任務切換使用 TSS + TR + JMP/CALL FAR 到 TSS 選擇子,或軟體模擬 (現代 OS 多用軟體切換)
CR3 寫入必須確保新頁目錄已建立且包含當前執行代碼映射,否則立即 Triple Fault
TLB 管理INVLPG (單頁失效)、寫 CR3 (全域失效)、PCID (Process Context ID, 後續架構)

總結

控制暫存器 (CR0-CR3) 與系統位址暫存器 (GDTR/IDTR/LDTR/TR) 是 x86 保護模式與分頁機制的指揮中樞。CR0 掌管模式與協處理器,CR2/CR3 服務分頁,四大系統暫存器定位描述符表與任務狀態。深入理解其位定義、交互約束、載入指令與副作用 (TLB 刷新、任務切換行為),是作業系統核心開發、Hypervisor 編寫、裝置驅動程式調試的必修內功。

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