簡要說明
所謂預處理器,就是在編譯階段由編譯器解釋執行的代碼,所以代碼的結果應該是在編譯階段就能確定,否則就會報錯。
強大的預處理器可以簡化和增強匯編代碼的能力。
單行宏
%define / %idefine
基本格式:
%define a mov ax,1
%define a(p1,p2) mov p1,p2
%define a(p1,p2,p3) P3 p1,p2
說明:
宏可以重載,也就是說可以定義米子相同參數不同的宏,使用的時候編譯器會根據參數類確定用哪一個,但是如果定義了不帶參數的,那么就不能重載了
%define 是區分大小寫的所以
%define Foo 和 %define foo 是不一樣的
%idefine 是忽略大小寫的版本
%xdefine/%ixdefine
說明:
與%define的區別是展開的時機不同
%define 是在使用的時候展開
%xdefine 是在定義的時候被展開,其中的區別可以用如下代碼演示
舉例1:
#define a 1 ; A=1
#define b a ; 因為是調用時展開,所以具體的內容得調用的時候確定A的內容后才能展開
#define a 0 ; A被重定義 = 0
mov ax, b
此時展開b
step1. mov ax, a
step2. mov ax, 0
舉例2
使用%xdefine 在定義是展開
#xdefine a 1 ; A=1
#xdefine b a ; 定義時展開,所以實際上就是 #xdefine b 1
#xdefine a 0 ; A被重定義 = 0
mov ax, b
此時展開b
step1. mov ax, b
step2. mov ax, 1
%+
說明:
字符連接,相當於MASM和C中的 & 的作用
舉例
#define a(b) student. %+ b
a(id) => student.id
%undef
說明:
取消宏定義
%assign/%iassign
說明:
定義常數的專用的%define
區別就在於%assign只能用於定義常數,同時定義形式可以是可以是表達式,
比如
%assign x 1 ; x=1
%assign x x+1 ;他會計算表達式的值所以 x=2 不是 1+1
多行宏
%macro / %imacro
基本格式:
%macro 宏名稱 參數數量
push ebp
mov ebp,esp
sub esp,%1
%endmacro
說明:
參數數量是一個數字,表示這個宏接收幾個參數
在宏定義中用 %數字來表示 第幾個參數,比如
%1 表示第一個參數 %2 表示第二個參數,索引從1 開始,%0表示的是參數的個數
可以重載帶不同參數數量的宏,因為就算不帶參數也是 寫 0 所以這里沒有不帶參數的宏定義后就不能重載的限制
使用
宏名字 參數1, 參數2 ,{
我是帶, 逗號的參數,需要使用括號括起來表示一個整體}
宏中的本地標簽
在MASM中宏中的本地標簽用的是.label的形式,nasm中使用 %%label的形式,這里注意區別
普通代碼中的本地標簽: .LABEL
宏定義中的本地標簽: %%LABEL
%macro a 0
jnz %%skip
ret
%%skip:
%endmacro
貪婪宏定義
在宏定義的參數數量后邊加上 + 加號,就表示這是一條貪婪宏定義
其含義就是多出來的參數被當成一個整體作為最后一個參數傳入
比如我如下兩個宏的定義
%macro M1 2+
%macro M2 2
那么
M1 PARAM1,PARAM2,PARAM3,PARAM4
M2 PARAM1, {PARAM2,PARAM3,PARAM4}
這兩個調用完全等價
指定參數范圍
%macro M1 1-4 默認參數2, ,默認參數4
這表示 這個宏的參數是 1- 4 個,有點類似c++的默認參數語法: void m(x1, x2=1,x3=3,x4=4);
其完整含義如下:
第一個參數的必須的
如果沒有第二個參數,就使用默認參數2,
如果沒有第三個參數,就使用默認參數3,因為沒有默認參數3, 就使用空
如果沒有第四個參數,就使用默認參數4
注意:支持通配符* 表示任意 比如 0-* 表示隨便幾個參數
支持貪婪定義,比如 0 - 4+
參數的連接
就是MASN和C中& 和&& 的作用,在單行宏定義中需要使用 符號 %+來連接,多行宏就不需要了,可直接使用
比如
%1abc ,abc%1
但是如果是數字則要這樣
%{1}123
123%1
.nolist
作用的在生成list文件的時候不要抱宏擴展出來,你生成list文件是希望將指令對照着2進制代碼去看的,這個時候如果保留宏,而不是將宏給擴展出來的話,可讀性會更好一點。
格式
%macro foo 1.nolist
%macro bar 1-5+.nolist a,b,c,d,e,f,g,h
%roate
格式:
%roate 左移個數
說明:
多行宏定義中的參數左移, 負數就是右移
比如
現在的參數是
%1 %2 %3 %4
a b c d
使用
%roate 2 結果如下
%1 %2 %3 %4
c d a b
有什么用呢?
舉例
%macro multipush 1-*
%rep %0
push %1
%rotate 1
%endrep
%endmacro
那么我無論 multipush 跟幾個寄存器,他都能正常push
同理
%macro multipop 1-*
%rep %0
%rotate -1
pop %1
%endrep
%endmacro