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

80386 任務狀態段 (TSS) 與控制門深度解析:硬體任務切換與特權轉移的核心機制

     編輯:組合語言

前言

在 80386 保護模式架構中,任務狀態段 (TSS) 與控制門 (Control Gates) 共同構成了硬體級任務管理與特權轉移的基石。TSS 保存任務完整上下文,控制門則提供受檢查的轉移入口。本文將系統剖析系統段描述符、各類門描述符、TSS 內部佈局、特權級轉移規則與任務切換流程。

一、系統段描述符:LDT 與 TSS 的元數據

1. 通用格式 (8 位元組)

位 63~56: 基址 31~24
位 55~52: G(粒度) D/B(預設大小) 0 AVL(可用) 界限 19~16
位 51~48: 界限 19~16 (續)
位 47:    P(段存在)
位 46~45: DPL(描述符特權級 0~3)
位 44:    DT(描述符類型) = 0 表示系統段
位 43~40: TYPE(系統段子類型)
位 39~32: 基址 23~16
位 31~16: 基址 15~0
位 15~0:  界限 15~0

關鍵區別:DT=1 為儲存段 (代碼/資料/堆疊);DT=0 為系統段。TYPE 欄位編碼完全不同:

TYPE系統段/門類型備註
1可用 286 TSS
2LDT 段僅能放於 GDT
3忙碌 286 TSS
4286 呼叫門16 位參數複製
5任務門
6286 中斷門
7286 陷阱門
9可用 386 TSS32 位上下文
B忙碌 386 TSS
C386 呼叫門32 位參數複製
E386 中斷門清 IF
F386 陷阱門保留 IF

只有 TYPE=1,2,3,9,B 是真正的系統段描述符 (描述記憶體段);其餘為門描述符 (描述轉移入口)。系統段選擇子不能直接讀寫段內容,需用別名技術 (建立對應資料段描述符) 訪問。

2. LDT 描述符範例

LDTABLE DESC <1Fh, 4321h, 65h, 82h, ,>  ; 界限=1Fh, 基址=654321h, DPL=0, TYPE=2(LDT)

載入 LLDT 指令時,描述符基址/界限/屬性自動載入 LDTR 隱藏快取。

3. TSS 描述符範例

TempTask DESC <104, 3456h, 12h, 89h, ,>  ; 界限=104(104 bytes), 基址=123456h, DPL=0, TYPE=9(可用386 TSS)

載入 LTR 或任務切換時,資訊載入 TR 隱藏快取。TYPE 位 0 (忙/可用) 由硬體自動維護:當前任務及鏈接任務為「忙」,其餘為「可用」。

二、門描述符:受控轉移的入口哨兵

1. 通用門格式 (8 位元組)

位 63~48: 偏移 31~16
位 47~16: 選擇子(16) + 屬性(16) + 雙字計數(5) + 000(3)
位 15~0:  偏移 15~0

屬性位組:P(1) DPL(2) DT=0 TYPE(4)。選擇子指向目標代碼段 (呼叫/中斷/陷阱門) 或 TSS 描述符 (任務門)。

2. 結構定義範例

GATE STRUC
OFFSETL DW 0      ; 偏移低 16
SELECTOR DW 0     ; 目標選擇子
DCOUNT  DB 0      ; 雙字計數 (僅呼叫門有效)
GTYPE   DB 0      ; P+DPL+DT+TYPE
OFFSETH DW 0      ; 偏移高 16
GATE ENDS

SUBRG GATE <3456h, 10h, , 8Ch+60h, 12h>  ; 386 呼叫門, 選擇子=10h, 偏移=123456h, DPL=3

3. 四大門類型功能對比

門類型選擇子指向偏移含義觸發指令/事件特權轉移參數複製
呼叫門代碼段描述符入口點偏移CALL FAR外層→內層 (CPL>DPL)依 DCOUNT 複製雙字參數至內層堆疊
任務門GDT 中 TSS 描述符無意義 (0)JMP/CALL FAR, Int/Exception任意級→目標任務任意級無 (新任務獨立上下文)
中斷門代碼段描述符ISR 入口偏移硬體中斷, INT n外層→內層 (同呼叫門)無 (硬體自動壓 EFLAGS/CS/EIP/錯誤碼)
陷阱門代碼段描述符處理程序入口異常, INT n外層→內層無 (同中斷門,但保留 IF)

核心差異:中斷門進入時清 IF (屏蔽可屏蔽中斷);陷阱門保留 IF。呼叫門獨有雙字計數字段,支援跨特權級參數傳遞。

三、任務狀態段 (TSS) 內部架構全景

386 TSS 基本區固定 104 位元組 (偏移 00h~67h),五大功能區:

1. 鏈接字段 (Offset 00h, 4 bytes)

  • 低 16 位:前一任務 TSS 選擇子;高 16 位保留 (0)。
  • 任務由 CALL/JMP/Int 經任務門激活時,硬體自動填入被掛起任務 TSS 選擇子,並置 EFLAGS.NT=1。
  • IRET (NT=1) 時沿此字段返回前一任務。

2. 內層堆疊指標區 (Offset 04h~1Fh, 24 bytes)

外層→內層轉移時,硬體自動從此區載入 SS:ESP;外層堆疊指標 (SS:ESP) 壓入新堆疊。硬體從不寫回此區,故內層堆疊視為「空堆疊」,不支援同級遞迴。

3. 位址映射暫存器區 (Offset 1Ch, 20h, 60h)

  • CR3 (Offset 1Ch, 4 bytes):頁目錄表物理基址。任務切換時自動載入 CR3,切換線性→物理映射。
  • LDTR (Offset 60h, 2 bytes):LDT 描述符選擇子。任務切換時自動載入 LDTR,切換虛擬→線性映射。

重要:硬體不自動儲存舊 CR3/LDTR 回 TSS。OS 若修改 CR3/LDTR,必須以別名技術手動更新 TSS 對應欄位。

4. 暫存器保存區 (Offset 20h~5Fh, 64 bytes)

依序保存:EIP、EFLAGS、EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI、ES、CS、SS、DS、FS、GS (各 4 bytes,段暫存器高 16 位置 0)。任務切出時自動存入,切入時自動恢復。

5. I/O 許可位圖基址與 T 旗標 (Offset 64h~66h)

  • Offset 64h (Word):I/O 位圖在 TSS 內偏移 (從 TSS 基址起算)。位圖大小可變,每 I/O 埠 1 位,CPL=3 存取時檢查。
  • Offset 66h (Word, 實為 64h 同字低位):T 旗標 (Bit 0)。=1 時任務切入後第一條指令前產生除錯陷阱 (向量 1)。

6. TSS 結構定義巨集 (MASM)

TSS STRUC
TRLink      DW 0, 0           ; 鏈接字段
TRESP0      DD 0              ; ESP0
TRSS0       DW 0, 0           ; SS0
TRESP1      DD 0              ; ESP1
TRSS1       DW 0, 0           ; SS1
TRESP2      DD 0              ; ESP2
TRSS2       DW 0, 0           ; SS2
TRCR3       DD 0              ; CR3
TREIP       DD 0              ; EIP
TREFlag     DD 0              ; EFLAGS
TREAX       DD 0              ; EAX
TRECX       DD 0              ; ECX
TREDX       DD 0              ; EDX
TREBX       DD 0              ; EBX
TRESP       DD 0              ; ESP
TREBP       DD 0              ; EBP
TRESI       DD 0              ; ESI
TREDI       DD 0              ; EDI
TRES        DW 0, 0           ; ES
TRCS        DW 0, 0           ; CS
TRSS        DW 0, 0           ; SS
TRDS        DW 0, 0           ; DS
TRFS        DW 0, 0           ; FS
TRGS        DW 0, 0           ; GS
TRLDTR      DW 0, 0           ; LDTR
TRTrip      DW 0              ; T 旗標 (Bit 0)
TRIOMap     DW ?              ; I/O 位圖偏移
TSS ENDS

四、任務切換完整流程

  1. 觸發源:JMP/CALL 任務門或 TSS 描述符、IRET (NT=1)、中斷/異常經任務門。
  2. 檢查目標 TSS 描述符:P=1、TYPE=可用 (1/9)、DPL ≥ CPL (任務門除外)。
  3. 儲存當前上下文至舊 TSS (暫存器區、CR3、LDTR 不自動存)。
  4. 標記舊 TSS 忙位=1,新 TSS 忙位=1 (若經任務門/CALL,舊 TSS 鏈接字段寫入新 TSS 選擇子,NT=1)。
  5. 載入 TR 可見部 = 新 TSS 選擇子,隱藏快取 = 新 TSS 基址/界限/屬性。
  6. 從新 TSS 載入:CR3、LDTR、暫存器區 (含 EIP/EFLAGS/通用暫存器/段暫存器)、SS0:ESP0~SS2:ESP2 (依 CPL 選擇)。
  7. 若新 TSS T 旗標=1,執行第一條指令前產生除錯陷阱。
  8. 開始執行新任務。

五、工程實踐要點

  • TSS 界限:386 TSS 至少 104 (068h) 位元組;含 I/O 位圖時界限 = 104 + 位圖大小 + 1 (終止位)。
  • 初始化順序:建立 GDT TSS 描述符 → 以別名寫入 TSS 初始值 (CR3、LDTR、SS0:ESP0 等) → LTR 載入 TR 啟動首個任務。
  • 嵌套任務:僅 CALL/JMP 任務門、中斷任務門會建立鏈接 (NT=1);IRET 返回時自動順鏈恢復。
  • 效能考量:硬體任務切換 ~300 週期,遠慢於軟體切換 (現代 OS 多用軟體切換 + TSS 僅作 Ring 0 堆疊與 I/O 位圖)。

結語

TSS 與控制門是 80386 實現硬體強制多任務隔離、特權受控轉移的雙引擎。雖然現代作業系統為效能多採用軟體調度,但 TSS 仍保留關鍵角色:Ring 0 堆疊指標、I/O 許可位圖、雙重錯誤/機器檢查等致命異常的專用 TSS。深入理解其結構與硬體流程,是作業系統核心開發、Hypervisor 編寫、安全研究的核心基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
偏移欄位大小用途
04hESP04Ring 0 堆疊頂 (SS0:ESP0)
08hSS02Ring 0 堆疊段選擇子
0ChESP14Ring 1 堆疊頂
10hSS12Ring 1 堆疊段選擇子
14hESP24Ring 2 堆疊頂
18hSS22Ring 2 堆疊段選擇子