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

Win32 組合語言教學:MessageBox 訊息框與 INVOKE 參數型別檢查

     編輯:組合語言

教學目標

以最精簡的 Win32 程式呼叫 MessageBox 顯示對話框,並深入解析 INVOKE 高層呼叫指令的參數型別檢查機制、ADDR vs OFFSET 差異、動態連結庫匯入庫鏈接流程。

最小程式碼

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
INCLUDE \MASM32\INCLUDE\WINDOWS.INC
INCLUDE \MASM32\INCLUDE\KERNEL32.INC
INCLUDELIB \MASM32\LIB\KERNEL32.LIB
INCLUDE \MASM32\INCLUDE\USER32.INC
INCLUDELIB \MASM32\LIB\USER32.LIB

.DATA
  MsgBoxCaption DB "Iczelion Tutorial No.2",0
  MsgBoxText    DB "Win32 Assembly is Great!",0

.CODE
START:
  INVOKE MessageBox, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK
  INVOKE ExitProcess, NULL
END START

MessageBox 原型與參數

MessageBox PROTO hWnd:DWORD, lpText:DWORD, lpCaption:DWORD, uType:DWORD
  • hWnd:父視窗控制代碼,NULL 表無擁有者,對話框置中於螢幕
  • lpText:訊息字串指標 (ANSI 版 MessageBoxA)
  • lpCaption:標題列字串指標
  • uType:按鈕/圖示/預設按鈕/模態類型組合,MB_OK = 僅確定鍵 + 資訊圖示

INVOKE 參數型別檢查機制

INVOKE 會依據 PROTO 宣告的參數型別,於組譯期檢查:

  • 參數個數是否符合
  • 每個參數大小是否匹配 (DWORD=4 位元組,WORD=2,BYTE=1,QWORD=8)
  • 立即數是否超出目標型別範圍

對比 CALL:CALL MessageBox 完全無檢查,若堆疊參數錯誤只會在執行期崩潰;INVOKE 編譯期即報錯,大幅降低除錯成本。

ADDR vs OFFSET 關鍵差異

前向參考範例

; 錯誤:ADDR 無法解析前向標號
INVOKE MessageBox, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK
...
MsgBoxCaption DB "...",0
MsgBoxText    DB "...",0

; 正確:改用 OFFSET
INVOKE MessageBox, NULL, OFFSET MsgBoxText, OFFSET MsgBoxCaption, MB_OK

區域變數範例

WndProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  LOCAL szBuf[256]:BYTE
  INVOKE lstrcpy, ADDR szBuf, ADDR SrcText  ; 正確:ADDR 產生 LEA 序列
  ; INVOKE lstrcpy, OFFSET szBuf, ...       ; 錯誤:OFFSET 無法取得堆疊位址
  RET
WndProc ENDP

動態連結庫匯入庫鏈接流程

  1. INCLUDE USER32.INC:引入 MessageBox PROTO ... 等原型宣告
  2. INCLUDELIB USER32.LIB:在 .obj 嵌入連結器指令「鏈接 USER32.LIB」
  3. ML /c /coff /Cp:產生 .obj (COFF 格式)
  4. LINK /SUBSYSTEM:WINDOWS /LIBPATH:C:\MASM32\LIB file.obj:
    • 讀取 USER32.LIB 匯入庫,解析 MessageBox 等符號
    • 在可執行檔 .idata 區建立匯入表:DLL 名稱 + 函數名/序數
    • 修正 CALL [IAT_MessageBox] 等指令位址
  5. 執行時:Windows 載入器依匯入表載入 USER32.DLL,填入 IAT 實際位址

ANSI vs Unicode 版本

  • MessageBoxA (ANSI):字串為單位元組字元,windows.inc 以 MessageBox EQU 為預設
  • MessageBoxW (Unicode):字串為雙位元組寬字元,需定義 UNICODE 宏或直接呼叫 MessageBoxW
  • 現代建議:統一使用 Unicode 版本,字串前綴 L"..." 或 _TEXT("...")

建置與驗證

ML /c /coff /Cp MSGBOX.ASM
LINK /SUBSYSTEM:WINDOWS /LIBPATH:C:\MASM32\LIB MSGBOX.OBJ
; 產生 MSGBOX.exe (約 1.5 KB),執行即見對話框
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
運算子適用範圍機制限制
OFFSET全域/靜態變數組譯期解析位址,直接嵌入機器碼無法處理區域變數 (堆疊相對位址)
ADDR全域/靜態/區域變數組譯期檢查:全域同 OFFSET;區域產生 LEA EAX, var / PUSH EAX 序列無法處理前向參考 (變數定義在 INVOKE 之後)