天天看點

學Win32 彙編[2]: 最簡單的 Win32 程式

; Test2_1.asm

.386

.model flat, stdcall

include windows.inc

include user32.inc

include kernel32.inc

includelib user32.lib

includelib kernel32.lib

.data

    szCaption db 'Hi', 0

    szMsg     db 'Hello World!', 0

.code

start:

    invoke MessageBox, NULL, addr szMsg, addr szCaption, MB_OK

    invoke ExitProcess, NULL

end start

--------------------------------------------------------------------------------

建立過程:

1、檔案 -> 建立工程 -> 工程類型: Win32 App (no res)、工程名稱: Test1 -> 預設下去到完成.

2、打開 Test1.asm 輸入以上代碼, 然後編譯執行. 結果如下:

學Win32 彙編[2]: 最簡單的 Win32 程式

程式注釋:

; Test1.asm
; 分号是單行注釋

comment &
  注釋還可以使用 comment, 現在兩個 & 之間的是注釋内容, 其中的百分号也可以換做其他符号, 譬如 ^
&

COMMENT ^
  這也是注釋, 
  還是多用 ; 吧, 比較友善 ^

; ********************************

.386
.model flat, stdcall

;.386 和 .model 都是是彙編僞指令; .386 表示使用 386 指令集, 這是 Win32 程式的最低需求.
;類似的還有 .8086 .286 .386p .486 .486p .586 .586p .mmx 等, 其中的 p 表示可以使用一些特權指令.

;.model 用于定義工作模式;
;flat 是記憶體模式, 類似還有: tiny small medium compact large huge, Win32 程式隻能選擇 flat;
;stdcall 是語言模式, 類似的還有: c syscall basic fortran pascal, 使用 Win32 API 必須選擇 stdcall.

; ********************************

include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

;kernel32.dll 是系統服務接口, 負責記憶體管理等;
;user32.dll 是使用者服務接口, 負責消息管理等;
;下面的程式會用到它們的函數.

;user32.inc 和 kernel32.inc 中分别包含着對應 DLL 的函數、常量、結構的聲明.
;windows.inc 包含着 Win32 程式用到的常量、結構的聲明; 譬如下面用到的 MB_OK 常量就是在其中聲明.

;程式在編譯時, 見到 include (僞)指令就會把它指定的 inc 檔案(或 asm) 檔案複制到目前位置.
;inc 檔案主要包含函數或常量的聲明.

;lib 檔案包含了動态庫函數的位址資訊和靜态庫的函數代碼, 程式在連結階段會提取這些資訊或代碼; 
;對 DLL(動态庫), 程式運作時會根據這些位址資訊去調用 DLL 中的相應的函數.

;inc 和 lib 檔案分别存放在 masm32/include/ 和 masm32/lib/ 下;
;這裡沒有使用路徑是因為 RadASM 已經給設定好了系統路了.

; ********************************

.data
    szCaption db 'Hi', 0
    szMsg     db 'Hello World!', 0

;.data 說明這是程式的資料段, 下面的 .code 是代碼段
;後面還會接觸到 .const(常量段)、.data?(變量段)等

;這裡是定義了兩個字元串變量 szCaption、szMsg, 後面的 0 表示是 0 結束的字元串.
;關于 db 等後面詳細探讨.

; ********************************

.code
start:
    invoke MessageBox, NULL, addr szMsg, addr szCaption, MB_OK
    invoke ExitProcess, NULL
end start

;這段程式用到了兩個 API 函數: MessageBox(顯示消息框)、ExitProcess(退出程式);
;這兩個函數分别來自 user32.dll 和 kernel32.dll.

;invoke 是調用函數或子過程的僞指令.
;addr 是取位址的僞指令, 這裡也可以換做 offset

;start 是随便命名的标号, 用于表示程式段的開始和結束

;另外彙編本來是不區分大小寫的, 但在使用 WinAPI 和 C 函數時必須注意大小寫
;标号(如 start)和變量也要注意大小寫
;指令和僞指令大小寫均可

;彙編會忽略多餘的空白, 并用 / 續行, 譬如:
invoke MessageBox, NULL, addr szMsg, addr szCaption, MB_OK
;可寫作:
invoke MessageBox, NULL,/ 
                   addr szMsg,/
                   addr szCaption,/
                   MB_OK

        

關于換行: 在實際操作中, 我沒有使用換行符号 / 也可以, 如:

; Test2_1.asm

.386
.model flat, stdcall

include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

.data
    szCaption db 
      'Hi', 0
    szMsg     db 'Hello World', 
                 '!', 0

.code
start:
    invoke MessageBox, NULL, 
                       addr szMsg, 
                       addr szCaption, 
                       MB_OK
    invoke ExitProcess, NULL
end start

        

繼續閱讀