Win32彙編教程二 Win32彙編程式的結構和語法
Win32彙編程式的結構和語法
--------------------------------------------------------------------------------
Win32ASM程式的結構和語法
讓我們先來看看一個最簡單的Win32彙編程式:
.386
.model flat, stdcall
option casemap :none ; case sensitive
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
szCaption db 'Win32彙編例子',0
szText db 'Win32彙編,Simple and powerful!',0
.code
start:
invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
invoke ExitProcess,NULL
end start
這就是一個能執行的最簡單的Win32彙編程式,下面我簡單地介紹一下各部分的作用:
.386
這條語句和Dos下彙編是一樣的,是告訴編譯器我們要用到80386的指令集,因為32位彙編程式要用到32位的暫存器如eax,ebx等,所以這一句是必須的,當然,你也可以用.486,.586等,當用到特權指令時,還可以用 .386p,.486p等等。
.model flat,stdcall
.model告訴編譯器程式的模式,編過Dos彙編的人可能知道在Dos程式的模式有tiny,small,...huge 等,它指定了程式記憶體定址模式,在huge等模式下,記憶體定址和子程式呼叫將用Far的格式,但在Win32彙編中,你只能使用一個模式即 flat 模式,因為對Win32程式來說,記憶體是連續的一個4GB的段,無所謂小或大的模式。而stdcall 告訴編譯器引數的傳遞方式,在呼叫子程式時,引數是通過堆疊傳遞的,引數的傳遞方式有三種,stdcall,c 和 pascal,stdcall 指定了引數是從右到左壓入堆疊的,比如說對一個Windows API 如 MessageBox,在手冊中是如此定義的:
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
那麼在彙編中我們就可以這樣呼叫它:
push uType
push lpCaption
push lpText
push hWnd
call MessageBox
大家要注意最右面的引數是最後一個進堆疊的,當然,我們不必這樣麻煩的呼叫一個 API,因為Masm中的一個巨集語句不但幫助我們完成了所有的壓棧操作,還幫我們檢查引數的個數是否正確,那就是 invoke 語句,我們可以把上面的語句換成 invoke MessageBox,hWnd,lpText,lpCaption,uType 就行了。如本程式中代入實際引數就成了 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK。
include 語句
include 語句包含了一些系統的定義和API函說明,其中所有的Windows 資料結構定義和常量定義包含在 windows.inc 中,而其他 API函式的說明包含在 xxx.inc 中, 如查 Microsoft Win32 Programmer's Reference 知道 ExitProcess包含在kernel32.dll 中,那麼我們就要在程式中包括 include kernel32.inc 和 includelib kernel32.lib語句,否則在編譯時會出現 API 函式未定義的錯誤。而 MessageBox 在 user32.dll 中,那麼我們就要在程式中包括 include user32.inc 和 includelib user32.lib語句
.data 或 .data?
指明瞭接下來是資料段,.data 定義了預定義的變數,.data?定義了未初始化的變數,兩者的不同之處是 .data? 定義的變數並不佔用 .exe 檔案的大小,而是在程式執行時動態分配,所以開始是不指定初始值的資料可以放在 .data? 段中,如一個1K大小的緩衝區,放在 .data?中,程式將不會增加一個位元組。
.code
指明瞭接下來是程式碼段,我們的所有程式碼都放在這裡。最後的一句 start 語句指定了程式開始執行的語句。程式中的 ExitProcess 是一個標準的 Win32 API,對應 Dos彙編中的 int 20h 或 mov ah,4ch/int 21h,也就是程式退出。而 MessageBox 也是一個標準的 API,功能是在螢幕上顯示一個訊息框,具體的引數上面已經解釋過了還有要注意的是 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK 語句中, MB_OK 和 NULL 已經預定義在 Windows.inc 中。