NASM中的Preprocessor都以%开头。
单行macro %define
%define与C语言中的#define类似:
%define a(x) 1+b(x)
%define b(x) 2*x
mov ax,a(8) ;展开后是mov ax 1+2*8
%define不会无限expansion,只会expansion一次,比如:
%define a(x) 1+a(x)
mov ax, a(3); 只会展开一次,展开后mov ax 1 + a(3)
%define支持overload,比如:
%define foo(x) 1+x
%define foo(x,y) 1+x*y
foo(3)使用单参数版本:1+3
foo(2, 3)使用2参数版本:1+2*3
需要注意的是,如果定义了有参数的macro,就不能在定义没有参数的macro:
%define foo bar;不被允许了
同样,如果定义了无参数的macro,那么就不能在定义有参数的macro。
对于无参数的macro来说,可以被重定义(Redefine):
%define foo bar
%define foo baz;后定义的macro将覆盖前面定义的macro
%define区分大小写:
%define foo bar;只对foo会expansion成bar,foO Foo不起作用
;如果需要会略大小写,使用%idefine
NASM2.15中的新特性:
%define erge(x, ) x*2;逗号后面没有指名参数名,那么调用这个macro是从第2个参数起就会被忽略
erge(1, 2, 3);参数2, 3会被忽略
;macro参数前有=,expansion的时候会被求值
;macro参数前有&,expansion的时候会变成字符串
;macro参数后有+,表示是一个greedy参数,它将包含后续所有参数
;macro参数前有!,空格和{}不会被移除
%define xyzzy(=expr,&val) expr, str
%define plugh(x) xyzzy(x,x)
db plugh(3+5), ‘0‘ ; Expands to: db 8, "3+5", ‘ ‘
多行macro %macro
%macro prologue 1 ;prologue是macro名,1是参数个数
push ebp
mov ebp,esp
sub esp,%1 ;%1表示引用第一个参数,如果有第二个,第三个参数,可以使用%2, %3引用
%endmacro
%macro silly 2
%2: db %1
%endmacro
silly ’a’, letter_a ; letter_a: db ’a’
silly ’ab’, string_ab ; string_ab: db ’ab’
silly {13,10}, crlf ; crlf: db 13,10 参数里面想包含,用{}包围
和单行macro一样,多行macro也可以被overload,不同之处在于,如果之前定义了无参多行macro,同样也可以overload有参多行macro。