程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> Win32匯編程序的結構和語法

Win32匯編程序的結構和語法

編輯:匯編語言

前言

我們了解了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 中。

待續...

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved