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

x86 組語實戰:從實模式切換到保護模式完整範例解析

     編輯:組合語言

本文深入剖析兩個經典的 x86 組語範例,詳細說明如何在 80386+ 處理器上實現實模式與保護模式的雙向切換,並展示保護模式下的分段記憶體管理、GDT/LDT 建立、特權級控制等核心概念。這些技術是作業系統核心開發、Bootloader 編寫及底層系統程式設計的基礎。

範例一:16 位代碼段切換演示

核心邏輯流程

  1. 準備階段: 建立全域描述符表(GDT),包含空描述符、代碼段、源數據段、目標數據段描述符;計算並填入段基址、界限、屬性。
  2. 載入 GDTR: 使用 LGDT 指令載入偽描述符指向 GDT。
  3. 進入保護模式: 關中斷(CLI)、開啟 A20 位址線、設定 CR0.PE=1、執行段間跳轉(JMP FAR)刷新預取隊列並載入 CS 選擇子。
  4. 保護模式下操作: 載入 DS/ES 選擇子,使用 REP MOVSD 將高端記憶體(110000H)資料搬移至常規記憶體緩衝區。
  5. 返回實模式: 清除 CR0.PE、段間跳轉回實模式代碼段、關閉 A20、開中斷(STI)、恢復實模式段寄存器、顯示結果。

關鍵技術點解析

GDT 建構與描述符初始化

範例在 .data 區定義 GDT 結構,運行時動態計算各段的 32 位線性基址(段值 × 16 + 偏移),填入描述符的 BaseL/BaseM/BaseH 欄位。所有段界限設為 0xFFFF(64KB),屬性為 16 位代碼/數據段(D/B=0)。

實模式 → 保護模式 的「跳躍」機制

設定 CR0.PE=1 後,處理器進入保護模式,但 CS 仍存放實模式段值。必須立即執行一條 段間直接轉移指令(JMP FAR),將保護模式代碼段選擇子載入 CS,同時指定新 EIP。此指令在實模式被預取、在保護模式執行,完成真正的模式切換。

A20 位址線控制

透過鍵盤控制器端口(92H)開啟/關閉 A20 Gate,允許存取 1MB 以上記憶體。此操作與處理器模式無關,純屬平台硬體控制。

段描述符快取暫存器的隱藏行為

返回實模式前,需載入一個符合實模式需求的描述符(如範例中的 Normal 描述符)到 DS/ES,以更新段描述符快取中的界限(0xFFFF)與屬性,確保實模式下段寄存器行為正確。


範例二:32 位與 16 位保護模式代碼段互相切換

此範例展示更進階的場景:從實模式進入 32 位保護模式代碼段,再切換至 16 位保護模式代碼段,最後返回實模式。

新增關鍵要素

  • 32 位代碼段描述符: 屬性位 D=1(D32 EQU 40h),預設操作數/位址大小為 32 位,使用 ESI/EDI/ECX 進行串操作。
  • 保護模式堆疊: GDT 新增堆疊段描述符,切換至 32 位代碼時載入 SS:ESP,支援 CALL/RET/PUSH/POP。
  • 32 位 → 16 位代碼段轉移: 使用 48 位全指標(選擇子:32位偏移)的 JMP FAR 指令。
  • 直接操作顯示緩衝區: 利用 0xB8000 文字模式顯存,在保護模式下直接寫入字元屬性,無需 BIOS 中斷。

返回實模式的關鍵步驟

在 16 位保護模式代碼段中,執行 MOV CR0, EAX (PE=0) 後,必須立即執行 JMP FAR 回實模式入口。同樣需預先載入符合實模式語意的描述符選擇子到 DS/ES/SS,確保段快取狀態正確。


核心知識總結

項目實模式保護模式
位址形成段值×16+偏移(20位)選擇子→描述符→基址+偏移(32位線性位址)
分段保護無特權級(DPL/RPL/CPL)、界限檢查、類型檢查
代碼段預設16位由描述符 D 位決定(16/32位)
中斷處理IVT (0:0)IDT(中斷/陷阱/任務門)
切換關鍵CR0.PE=0CR0.PE=1 + 載入有效 CS 選擇子

簡化與限制說明

兩個範例均為教學簡化模型:

  • 未建立 IDT(中斷描述符表),全程 CLI 關中斷運行,假設無異常發生。
  • 未使用 LDT(局部描述符表),所有選擇子指向 GDT(TI=0)。
  • 特權級均為 0(DPL=RPL=CPL=0),未展示跨特權級呼叫/門機制。
  • 未啟用分頁機制(CR0.PG=0),線性位址等於物理位址。

掌握這兩個範例,即掌握了 x86 保護模式程式設計的骨架。進階開發需深入研究 IDT、LDT、任務狀態段(TSS)、呼叫門、中斷門、分頁機制及多任務切換。

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