前言
我們了解了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 中。
待續...