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

深入解析 x86 保護模式下的異常處理機制:實例七完整演示

     編輯:組合語言

前言

在 x86 保護模式程式設計中,異常處理是核心且複雜的課題。本文透過一個完整的組合語言實例(實例七),詳細演示如何模擬並處理多種常見的處理器異常,包括除法錯誤、溢出、段不存在、堆疊段錯誤與通用保護故障。同時展示如何利用任務門實現獨立任務的鍵盤輸入處理。此實例對於理解中斷描述符表(IDT)、任務狀態段(TSS)、局部描述符表(LDT)的實際運作極具參考價值。

實例架構概覽

程式包含兩個獨立任務:演示任務與讀鍵盤任務。主要組成部分:

  • 全域描述符表(GDT)與中斷描述符表(IDT)
  • 讀鍵盤任務的 LDT、TSS、堆疊段、代碼段
  • 演示任務的 LDT、TSS、堆疊段、代碼段、數據段
  • 各類異常處理程序代碼段(除法錯誤、溢出、段不存在、堆疊段、通用保護)
  • 顯示錯誤碼的公共子程序代碼段
  • 實模式下的啟動與結束代碼段

切換到保護模式後進入臨時代碼段,演示任務不發生特權級變換,簡化了演示邏輯。

核心演示流程

  1. 從臨時代碼段轉移至演示代碼段
  2. 初始化演示任務環境:載入 LDTR、填充 TSS、載入 TR、建立堆疊、設置段寄存器
  3. 通過 INT 0FFh 調用讀鍵盤任務(任務門),接收用戶輸入的異常類型字符(0、4、B、C、D)
  4. 根據輸入字符故意執行觸發對應異常的指令
  5. 結束演示,返回實模式 DOS

關鍵異常處理程序分析

1. 除法錯誤故障(向量 0)

故意執行 DIV CL(被除數 2000,除數 2)觸發。處理程序顯示提示後,將 AX 右移一位(除以 2),然後 IRETD 返回。因為是 Fault,指令會重新執行,經過幾次處理後被除數變小,不再觸發故障。

2. 溢出陷阱(向量 4)

執行 INTO 觸發。處理程序僅顯示提示並返回。屬於 Trap,返回下一條指令繼續執行。

3. 段不存在故障(向量 0Bh)

將 P=0 的選擇子載入 GS 觸發。處理程序顯示提示、彈出錯誤碼、調用顯示錯誤碼子程序、調整返回地址(+2 字節)後 IRETD,跳過故障指令。

4. 堆疊段故障(向量 0Ch)

透過超出段界限的堆疊訪問指令觸發。處理邏輯類似段不存在,調整返回地址 +4 字節。

5. 通用保護故障(向量 0Dh)

將系統段描述符選擇子載入 GS 觸發。處理程序保護現場、顯示提示與錯誤碼、調整返回地址 +2 字節、清除錯誤碼後返回。

讀鍵盤任務的獨特實現

IDT 中 0FFh 為任務門,指向獨立 TSS。演示任務執行 INT 0FFh 發起任務切換。讀鍵盤任務為簡化在實模式下運作:

  1. 切換至實模式,恢復必要現場
  2. 調用 DOS/BIOS 中斷顯示提示、讀取鍵盤,驗證字符範圍
  3. 將字符存入約定緩衝區
  4. 切回保護模式,IRETD 觸發反向任務切換返回演示任務

任務代碼段中 IRETD 後緊跟 JMP GKeyBegin,確保下次進入時從頭開始執行。

完整源碼結構

源碼採用 TASM/TLINK 開發,包含完整的 GDT/IDT 定義、各任務 LDT/TSS/代碼/數據段、異常處理入口、顯示子程序、實模式啟動代碼。關鍵宏定義見 386SCD.INC。程式展示了保護模式下多任務、異常處理、任務門切換的實戰範本。

總結

實例七通過精心設計的指令序列模擬真實異常場景,配合完整的描述符表與任務結構,直觀展示了 x86 保護模式異常處理的核心機制。特別是任務門實現的鍵盤輸入任務,演示了硬體任務切換的自動現場保存/恢復特性。雖然演示代碼為教學簡化(如未完整保護現場),但架構完整,極適合深入研讀保護模式程式設計。

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