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

學 Win32 匯編[34] - 宏匯編

編輯:Delphi

從接觸 C 語言時, 我就不大喜歡宏; 但為了看懂別人的代碼也不得不去了解.

  宏可定義在源程序的任意位置, 但一般放在 .data 前面.

  有些簡單的宏可以用 equ、textequ 或 = 來代替, 但宏有更復雜的功能.

  "宏" 的本質是 "替換", 但又像極了 "子過程";

  所以即有宏過程(macro procedure)、也有宏函數(Macro function).

  它既以有參數, 有時也需要像子過程一樣聲明.

  宏可以指定哪些參數是必須的, 還可以給參數默認值.

  宏可以包含數據(.data)和代碼(.code)、還可以嵌套.

  宏中的注釋使用 ;; 如果只用 ; 將會被一起替換到代碼中.

  宏的功能很強大, 現在常用的 PrintDec、PrintHex、PrintString、PrintText 等等都是宏.

  再強大它也只是 "文本替換".

  "宏" 和 "子程序" 相比:

  1、宏展開後順序執行, 不像調用子程序跳來跳去, 這樣程序會更 "快";

  2、宏展開後會讓代碼量增大, 導致程序變 "大".

  一個簡單的宏:

; Test34_1.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
;定義一個 mExit 宏 
mExit Macro 
   PrintLine 
   ret 
endm 
 
.code 
sum proc v1, v2, v3 
   mov eax, v1 
   add eax, v2 
   add eax, v3 
   ret 
sum endp 
; 
main proc 
   invoke sum, 11, 22, 33 
   PrintDec eax ;66 
  ;PrintLine 
  ;ret 
   mExit ;mExit 將被替換為上面兩行代碼 
main endp 
end main 

 一個代替求和函數的宏:

; Test34_2.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
mSum Macro v1, v2, v3 
   mov eax, v1 
   add eax, v2 
   add eax, v3 
endm 
 
.code 
main proc 
   mSum 11, 22, 33 
   PrintDec eax ;66 
   PrintLine 
   mSum 11, 22, 33, 44, 55 ;多余的參數會被忽略 
   PrintDec eax ;66 
   PrintLine 
   ret 
main endp 
end main 

  宏參數的默認值:

; Test34_3.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
;參數 v1、v2 通過 REQ 標識說明是必備參數 
;參數 v3、v4 給出了默認值 
mSum Macro v1:req, v2:req, v3:=<33>, v4:=<44> 
   mov eax, v1 
   add eax, v2 
   add eax, v3 
   add eax, v4 
endm 
 
.code 
main proc 
   mSum 11, 22 
   PrintDec eax ;110 
   PrintLine 
   ret 
main endp 
end main 

  EXITM: 退出宏

; Test34_4.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
mPrint Macro 
   PrintText '第一行' 
   PrintText '第二行' 
   exitm 
   PrintText '第三行' 
endm 
 
.code 
main proc 
   mPrint ;只會輸出前兩行 
   ret 
main endp 
end main 

  PURGE: 取消宏

; Test34_5.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
mPrint Macro 
   PrintText '第一行' 
   PrintText '第二行' 
   PrintText '第三行' 
   PrintLine 
endm 
 
.code 
main proc 
   mPrint 
   mPrint 
   purge mPrint ;可用逗號隔開取消多個宏 
   mPrint    ;這個宏不會展開了 
   ret 
main endp 
end main 



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