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

組語實作:跨平台獲取作業系統版本(DOS 與 Windows 雙模式)

     編輯:組合語言

雙模式設計思路

利用 PE 格式的 Stub 機制:同一個 EXE 檔案在 DOS 下執行 Stub 代碼,在 Windows 下執行 PE 主程式。本程式實現兩套邏輯:

  • **DOS 環境**:調用 INT 21h/30h 獲取 DOS 版本,並透過檢查中斷向量 INT 08h、INT 43h 的偏移地址識別具體 DOS 產品(MS-DOS 7.0/7.1、UCDOS、PDOS95 等)
  • **Windows 環境**:調用 GetVersionEx API 獲取詳細版本資訊(平台 ID、主/次版本號、建置號、CSD 版本)

DOS 端核心代碼 (os_type.asm)

MOV AH, 30H
INT 21H             ; AL=主版本, AH=次版本
; 轉換為 ASCII 顯示
MOV AX, 3508H
INT 21H             ; 獲取 INT 08h 向量 -> ES:BX
CMP BX, 1FH         ; MS-DOS 7.00
JE  @END
CMP BX, 18DEH       ; MS-DOS 7.10
JE  @END
CMP BX, 1AEBH       ; UCDOS 98
JE  @REPORT_UCDOS98
CMP BX, 1AF3H       ; UCDOS
JE  @REPORT_UCDOS
CMP BX, 0A50H       ; PDOS95
JE  @REPORT_PDOS95
; ... 顯示對應字串

關鍵子程式 bin2dec:將 AH 中的二進制版本號轉為十進制 ASCII 字串(除 10 取餘疊代)。

Windows 端核心代碼 (StubDemo.asm)

.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib

.data
szMsgBoxTitle db '當前作業系統',0
szWin31       db 'Windows 3.1',0
szWin9x       db 'Windows 95',0
szWinNT       db 'Windows NT',0
szFormat      db '%lu.%lu.%lu',0
szFail        db '取得作業系統資訊失敗!',0

.data?
OsVer OSVERSIONINFO <>
szOsVerInfo  db 255 dup(?)
szOsVerInfoTmp db 255 dup(?)

.code
start:
    MOV OsVer.dwOSVersionInfoSize, SIZEOF OSVERSIONINFO
    INVOKE GetVersionEx, ADDR OsVer
    .IF EAX
        MOV EAX, OsVer.dwPlatformId
        .IF EAX == VER_PLATFORM_WIN32s
            MOV ESI, OFFSET szWin31
            AND OsVer.dwBuildNumber, 0FFFFH
        .ELSEIF EAX == VER_PLATFORM_WIN32_WINDOWS
            MOV ESI, OFFSET szWin9x
            AND OsVer.dwBuildNumber, 0FFFFH
        .ELSE
            MOV ESI, OFFSET szWinNT
        .ENDIF
        INVOKE lstrcpy, ADDR szOsVerInfo, ESI
        INVOKE wsprintf, ADDR szOsVerInfoTmp, ADDR szFormat, \
                OsVer.dwMajorVersion, OsVer.dwMinorVersion, OsVer.dwBuildNumber
        INVOKE lstrcat, ADDR szOsVerInfo, ADDR szOsVerInfoTmp
        INVOKE lstrcat, ADDR szOsVerInfo, ADDR OsVer.szCSDVersion
        MOV EDI, OFFSET szOsVerInfo
        MOV ESI, MB_OK OR MB_ICONINFORMATION
    .ELSE
        MOV EDI, OFFSET szFail
        MOV ESI, MB_OK OR MB_ICONWARNING
    .ENDIF
    INVOKE MessageBox, NULL, EDI, ADDR szMsgBoxTitle, ESI
    INVOKE ExitProcess, NULL
END start

編譯與鏈接為帶 Stub 的 PE

; 1. 編譯 DOS Stub
tasm os_type.asm
tlink os_type.obj
exe2bin os_type.exe stub.exe   ; 轉為 .COM 格式作為 Stub

; 2. 編譯 Windows 主程式
ml /c /coff StubDemo.asm
link /subsystem:windows /stub:stub.exe StubDemo.obj

執行生成的 StubDemo.exe:

  • DOS/命令提示字元下 → 顯示 DOS 版本詳細資訊
  • Windows GUI 環境下 → 彈出視窗顯示完整 Windows 版本

技術亮點

  1. **中斷向量指紋識別**:不同 DOS 產品的 INT 08h/43h 向量地址固定,作為可靠指紋
  2. **條件組譯**:UseStack、bDetailInfo 控制堆疊段與顯示詳略
  3. **PE Stub 機制**:連結器 /STUB 選項無縫融合兩套代碼
  4. **版本資訊完整解析**:平台 ID、版本號、建置號、Service Pack (CSDVersion) 一網打盡

此範例展示了組合語言在底層系統資訊獲取與跨環境相容性上的獨特優勢,是學習混合模式程式設計的經典教材。

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