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

從零打造磁碟分區掃描器:prw.asm 核心邏輯與 BIOS Int 13h 深度實戰

     編輯:組合語言

專案背景與目標

本文呈現一款純組合語言編寫的磁碟工具 prw.asm,功能對標 DOS 7.1 FDISK.EXE 與 PowerQuest PQMAGIC.EXE。程式在 486DX2 平台上運行,支援雙 IDE 控制器(Primary/Secondary,IRQ 14/15)、Master/Slave 雙通道、多種定址模式(CHS/LBA/LARGE),能完整掃描硬碟分區表、遞迴解析擴展分區邏輯鏈、依照 FDISK/PQMAGIC 規則分配邏輯磁碟機代號(C:~Z:,超出以 ^ 代替),並提供扇區級讀寫/備份功能。

一、硬體環境與 BIOS Int 13h 參數規範

1. 磁碟編號規則

DOS/Win98 依序掃描 Primary Master(80h)、Primary Slave(81h)、Secondary Master(82h)、Secondary Slave(83h),跳過空通道。啟動序由 BIOS Boot Sequence 決定。

2. 傳統 CHS 讀寫 (AH=02h/03h)

暫存器含義範圍/編碼
AH02h=讀 / 03h=寫
AL扇區數低 6 位有效 (1~63)
ES:BX緩衝區實模式位址
CH柱面號低 8 位0~1023
CL位 0~5:扇區號(1起);位 6~7:柱面號高 2 位
DH磁頭號0~15/254
DL磁碟號00h/01h=軟碟;80h~=硬碟

3. 三種定址模式容量上限

  • NORMAL (CHS):1024×16×63×512 B = 528 MB
  • LBA:磁頭 255,柱面 1024,扇區 63 → 8.4 GB
  • LARGE:柱面 >1024 時,控制器呈現 柱面/2、磁頭×2 給 Int 13h → 1 GB

4. 擴展 Int 13h (AH=42h/43h) 線性 64 位 LBA

使用 16 位元組擴展參數塊 extblk:

extblk  db 16, 0          ; 區塊大小、保留
sec_tot dw 1              ; 扇區數
buf_off dw offset buf     ; 緩衝區偏移
buf_seg dw seg buf        ; 緩衝區段值
lbal    dw 0              ; LBA 低雙字低字
lbah    dw 0              ; LBA 低雙字高字
        dd 0              ; LBA 高雙字 (共 64 位)

CHS↔LBA 互轉公式:
LBA = C × SPC + H × SPT + (S-1)
C = LBA / SPC; H = (LBA % SPC) / SPT; S = (LBA % SPT) + 1
其中 SPC=每柱面扇區數、SPT=每磁道扇區數。

二、主開機記錄 (MBR) 與分區表結構

每顆硬碟 0 磁柱 0 磁頭 1 扇區 (CHS) 為 MBR,偏移 1BEh 起連續 4×16 位元組分區表項:

偏移大小欄位說明
00h1BootInd80h=啟動/作用中,00h=非啟動
01h3Start CHS起始磁頭/扇區/柱面 (編碼同 Int 13h)
04h1PartType分區類型代碼 (見下表)
05h3End CHS結束 CHS
08h4StartLBA分區前隱藏扇區數 (相對磁碟起始)
0Ch4NumSecs分區總扇區數

分區類型代碼速查

  • DOS 主分區:01h(FAT12)、04h/06h(FAT16)、0Bh/0Ch/0Eh(FAT32/LBA)
  • DOS 擴展分區:05h、0Fh(LBA)
  • 非 DOS:82h(Linux swap)、83h(Linux ext2/3/4)、07h(NTFS)、17h(Hidden NTFS) 等
  • 隱藏屬性:類型值高 4 位為 1 表隱藏 (如 14h=隱藏 FAT16<32M)

三、擴展分區邏輯鏈遞迴解析

擴展分區內部以單向鏈結串列組織邏輯分區:

  1. 擴展分區表項的 StartLBA 指向第一個邏輯分區的 EBR (Extended Boot Record)。
  2. EBR 結構同 MBR,偏移 1BEh 為當前邏輯分區描述,偏移 1CEh 為下一個 EBR 描述 (類型 05h/0Fh)。
  3. 鏈尾以類型 00h 結束。

程式 chain 子程式實現遞迴走訪:讀取 EBR → 顯示/記錄當前邏輯分區 → 取 1CEh 項的 StartLBA 加上擴展分區基址 → 循環至類型 00h。

四、邏輯磁碟機代號分配演算法 (仿 FDISK/PQMAGIC)

掃描順序固定為磁碟 80h→83h,每磁碟三階段:

  1. 階段 1:主分區
    掃描 4 項分區表,類型屬主分區者:
     • BootInd=80h → 分配下一代號 (首個作用主分區得 C:)
     • 無作用主分區 → 表項順序第一個主分區得代號
  2. 階段 2:擴展分區邏輯分區
    依鏈結順序,類型為主分區者依序分配代號。
  3. 階段 3:未分配代號的主分區與非 DOS 分區
    按 MBR 表項順序,主分區且未得代號者分配;非 DOS 分區僅顯示大小,不給代號。

代號超過 Z: 時,FDISK 繼續分配,PQMAGIC 停止,prw.asm 採用 ^ 符號標記。

五、prw.asm 核心模組架構與關鍵子程式

模組/子程式功能關鍵技術點
dospri掃描主分區、分配代號、記錄佔用表項Int 13h AH=201h 驗證磁碟存在;primk 表比對類型;fcbsz 記錄佔用項索引
dosext掃描擴展分區、啟動鏈遞迴檢測 extmk(05h/0Fh);取基址 entrydi:entryes;呼叫 chain
chain遞迴走訪 EBR 鏈讀 EBR (AH=201h) → pri_non 顯示/分配 → 累加基址跳轉下一 EBR
nondos處理剩餘主分區與非 DOS略過已佔用表項 (fcbsz) 與擴展類型
h_geo取得硬碟幾何參數優先 Int 13h AH=48h (擴展);失敗退回 AH=08h (傳統);計算 SPC/SPT
f_geo軟碟幾何參數讀 BPB (偏移 19h/24h/26h) 反推柱面/磁頭/扇區
chs2lba/lba2chsCHS↔LBA 雙向轉換64 位運算 (DX:AX);SPC/SPT 為除數
rw1by1單扇區讀/寫 (傳統/擴展/VxD)模式旗標 drv_p;VxD 路徑檢測緩衝區跨 4KB 頁、自動映射/釋放
INnib十六進位鍵盤輸入 (長度可配)轉換至 stk1 堆疊陣列;低字回傳 BX
Show格式化輸出分區資訊from80/logidrv/Boot/volume/Front/In 字串模板

六、V86 模式下繞過虛擬化限制直達硬碟 — VxD 技術深度解析

Windows 9x V86 監控器攔截 Int 13h,DOS 程式無法直接存取硬碟。prw 採用動態載入 VxD方案:

  1. 用戶程式 INT 2Fh/AX=1684h, BX=3180h 取得 VxD V86_API_Entry 入口 (ES:DI)。
  2. 呼叫入口傳遞模擬暫存器結構 CLIENT_STRUCT,VxD 內部執行 Exec_Int(0x13) 實體中斷。
  3. 緩衝區跨 4KB 頁邊界時,VxD 回傳 BP 修正值:
     BP < 4096 → 偏移量;
     BP = 4096 → 緩衝區已在 V86 可見區;
     BP = 0x1010 → 成功映射至 V86 第 0x10 頁;
     BP = 0x1110 → 映射失敗。
  4. 用戶程式依 BP 調整 ES:BX 重試,完成後釋放映射頁面。

配套 C++ 載入器 (CreateFile("\\\\.\\C.VXD", FILE_FLAG_DELETE_ON_CLOSE)) 實現按需動態載入/卸載。

七、實戰範例輸出與驗證

雙硬碟環境 (ST32140A 2.0 GB + QUANTUM 514 MB) 掃描結果:

80,C:,Boot:80,FAT:06,Front:0000003F,In:00101661   ; 1299 MB FAT16B 作用主分區
80,^,Boot:00,FAT:17,Front:001016A0,In:00047A00   ; Hidden NTFS 574 MB (^符號)
80,E:,Boot:00,FAT:0B,Front:001490A0,In:00046A00   ; FAT32 邏輯分區
81,D:,Boot:80,FAT:06,Front:0000003F,In:000E8A00   ; 472 MB 作用主分區
81,H:,Boot:00,FAT:01,Front:000E8A40,In:00011A00   ; FAT12 邏輯分區
...

與 FDISK/PQMAGIC 代號分配完全一致,驗證演算法正確性。

結語

prw.asm 以不足 2 KB 核心代碼,完整實現了從 BIOS 幾何參數獲取、CHS/LBA 雙模式存取、MBR/EBR 遞迴解析、三階段代號分配、V86 環境下的 VxD 突破五大核心難題。代碼結構清晰、模組解耦,是學習底層磁碟編程、BIOS 介面、實模式/V86 交互、VxD 開發的極佳教案與實用工具。

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