NASM中如何将宏的部分参数传递给另一个宏?
NASM宏参数传递:可变参数场景的两种实现
直接传递所有可变参数
如果只是要把当前宏的所有参数原封不动传给另一个宏,NASM提供了简洁的语法:用%*指代当前宏的全部可变参数,直接在调用目标宏时使用即可:
%macro A 1-* %rep %0 db %1 %rotate 1 %endrep %endmacro %macro B 1-* ; 把B的所有参数直接传给A A %* %endmacro
比如调用B 0x01, 0x03, 0x05,会完全等价于调用A 0x01, 0x03, 0x05,生成对应的db指令。
筛选传递奇数索引的可变参数
要只传递奇数位置(从1开始计数)的参数,需要结合NASM预处理器的循环、条件判断和参数旋转功能实现:
方案1:逐个传递奇数参数
如果目标宏(比如A)支持逐个处理参数,可以直接在循环里筛选调用:
%macro A 1-* %rep %0 db %1 %rotate 1 %endrep %endmacro %macro B 1-* %push ctx_odd %assign %%pos 1 ; 记录当前参数的位置,从1开始 %rep %0 %if (%%pos % 2) == 1 A %1 ; 只传递奇数位置的参数给A %endif %rotate 1 ; 旋转参数列表,让下一个参数移到%1的位置 %assign %%pos %%pos + 1 %endrep %pop %endmacro
方案2:打包所有奇数参数后一次性传递
如果需要把所有奇数参数打包成列表再传给A,可以先拼接参数集合,再一次性传递:
%macro A 1-* %rep %0 db %1 %rotate 1 %endrep %endmacro %macro B 1-* %push ctx_odd %assign %%pos 1 %define %%odd_args ; 初始化空的参数列表 %rep %0 %if (%%pos % 2) == 1 %define %%odd_args %%odd_args %1 ; 追加奇数位置的参数 %endif %rotate 1 %assign %%pos %%pos + 1 %endrep A %%odd_args ; 一次性传递所有筛选后的参数 %undef %%odd_args ; 清理临时变量 %pop %endmacro
关键细节:
%push和%pop用来创建局部上下文,避免宏内的临时变量(比如%%pos、%%odd_args)影响全局预处理器环境;- 带
%%前缀的变量是宏的局部变量,不会和外部变量冲突; %assign用于给预处理器变量赋值,%define用来动态拼接参数列表;- 这里的“奇数索引”以1为起始(
%1是第1位,%3是第3位),如果需要从0开始计数,调整%%pos的初始值和判断条件即可。
内容的提问来源于stack exchange,提问作者dawmd
相关产品推荐
相关产品推荐

