Windows API 函數儲存在系統 DLL 中(kernel32.dll、user32.dll、gdi32.dll 等)。組語程式透過匯入庫(.lib)在連結階段解析函數位址,執行時由載入器動態連結。開發流程:
ml.exe 編譯產生 .objlink.exe 連結產生 .exe.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.code
start:
invoke ExitProcess, 0
end start
.386:啟用 80386 指令集.model flat, stdcall:平坦記憶體模型,stdcall 呼叫慣例(Win32 標準)option casemap:none:區分大小寫(標號、API 名稱)include:插入標頭檔(常數、結構、巨集)includelib:告訴連結器引入哪個 .libinvoke:高層呼叫指令,自動處理參數壓堆疊與類型檢查ml /c /coff /Cp msgbox.asm
link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib msgbox.obj
/c:僅編譯不連結/coff:產生 COFF 格式目標檔/Cp:保留使用者定義符號大小寫/SUBSYSTEM:WINDOWS:指定 GUI 子系統(無主控台視窗)MessageBox PROTO hWnd:DWORD, lpText:DWORD, lpCaption:DWORD, uType:DWORD
hWnd:父視窗控制代碼,NULL 表示無擁有者lpText:訊息字串位址(以 0 結尾)lpCaption:標題列字串位址uType:圖示與按鈕樣式(MB_OK, MB_ICONINFORMATION 等).386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data
MsgCaption db "Iczelion Tutorial No.2", 0
MsgText db "Win32 Assembly is Great!", 0
.code
start:
invoke MessageBox, NULL, addr MsgText, addr MsgCaption, MB_OK
invoke ExitProcess, 0
end start
| 運算子 | 適用範圍 | 處理時機 | 區域變數支援 |
|---|---|---|---|
offset | 全域/靜態標號 | 編譯期 | 不支援 |
addr | 全域/靜態/區域變數 | 執行期 (區域變數) | 支援 (產生 LEA 指令) |
; 全域變數:兩者皆可
invoke MessageBox, NULL, offset MsgText, addr MsgCaption, MB_OK
; 區域變數 (在 PROC 內用 LOCAL 宣告):
LOCAL szBuf[128]:BYTE
invoke lstrcpy, addr szBuf, addr SrcText ; 必須用 addr
; invoke lstrcpy, offset szBuf, ... ; 錯誤:offset 無法處理執行期位址
A(如 MessageBoxA),字串為單位元組字元,以 0 結尾。W(如 MessageBoxW),字串為雙位元組寬字元。#ifdef UNICODE ... #define MessageBox MessageBoxW ...db "text", 0。RET n)invoke 會自動產生正確的壓堆疊與清理代碼,避免手寫 push/call 易出錯。
unresolved external symbol。invoke 會檢查,call 不會 → 執行期崩潰。/SUBSYSTEM:CONSOLE 會多出主控台視窗;主控台程式用 WINDOWS 會看不到輸出。option casemap:none 時,Start 與 start 是不同標號。大型專案應將常用常數、結構、巨集、函數原型集中在 .inc 檔,實作碼分散在多個 .asm,連結時一併輸入:
; main.asm
include mylib.inc
includelib mylib.lib
; ...
; mylib.asm
; 實作函數
; 編譯: ml /c /coff mylib.asm
; 建立靜態庫: lib /OUT:mylib.lib mylib.obj
Win32 組語開發的核心在於:理解 PE 載入機制、熟悉 API 呼叫慣例、善用 invoke 與標頭檔進行型別安全開發。本文的訊息框範例雖簡單,但包含了完整的開發流程、關鍵指令與常見坑點,是進階學習視窗程式、GDI 繪圖、多執行緒、網路程式設計的堅實基石。