Nasm 预处理器 - 通过变量寻址参数
Nasm preprocessor - Address parameter via variable
我需要编写很多 push
指令来推送不同的字符。我想为此使用一个宏。这是我到目前为止所做的:
%macro push_multi 1-* ; Accept between 1 and ∞ arguments
%assign i 1
%rep %0 ; %0 is number of arguments
push %{i}
%assign i i+1
%endrep
%endmacro
push_multi 'a', 'b', 'c' ; push 'a' then push 'b' then push 'c'
但是 nasm -E
的结果是:
push %i
push %i
push %i
我想要这个:
push 'a'
push 'b'
push 'c'
如何使用 assign
创建的变量来处理宏的第 n 个参数?
使用%rotate 1
,您可以将宏参数列表向左旋转 1 个元素。这有效地将列表中的下一个元素放在开头。列表中的第一个元素始终可以引用为 %1
。将它放在 %rep %0
循环中将允许您遍历宏参数列表中的所有元素。 %rotate
的 NASM documentation 表示:
%rotate is invoked with a single numeric argument (which may be an expression). The macro parameters are rotated to the left by that many places. If the argument to %rotate is negative, the macro parameters are rotated to the right.
在你的情况下这应该有效:
%macro push_multi 1-* ; Accept 1 or more arguments
%rep %0 ; %0 is number of arguments pass to macro
push %1
%rotate 1 ; Rotate to the next argument in the list
%endrep
%endmacro
如果你想做相反的列表,你可以用 -1
在相反的方向旋转,然后先做 %rotate
:
%macro push_multi 1-* ; Accept 1 or more arguments
%rep %0 ; %0 is number of arguments pass to macro
%rotate -1 ; Rotate to the prev argument in the list
; If at beginning of list it wraps to end of list
push %1
%endrep
%endmacro
我需要编写很多 push
指令来推送不同的字符。我想为此使用一个宏。这是我到目前为止所做的:
%macro push_multi 1-* ; Accept between 1 and ∞ arguments
%assign i 1
%rep %0 ; %0 is number of arguments
push %{i}
%assign i i+1
%endrep
%endmacro
push_multi 'a', 'b', 'c' ; push 'a' then push 'b' then push 'c'
但是 nasm -E
的结果是:
push %i
push %i
push %i
我想要这个:
push 'a'
push 'b'
push 'c'
如何使用 assign
创建的变量来处理宏的第 n 个参数?
使用%rotate 1
,您可以将宏参数列表向左旋转 1 个元素。这有效地将列表中的下一个元素放在开头。列表中的第一个元素始终可以引用为 %1
。将它放在 %rep %0
循环中将允许您遍历宏参数列表中的所有元素。 %rotate
的 NASM documentation 表示:
%rotate is invoked with a single numeric argument (which may be an expression). The macro parameters are rotated to the left by that many places. If the argument to %rotate is negative, the macro parameters are rotated to the right.
在你的情况下这应该有效:
%macro push_multi 1-* ; Accept 1 or more arguments
%rep %0 ; %0 is number of arguments pass to macro
push %1
%rotate 1 ; Rotate to the next argument in the list
%endrep
%endmacro
如果你想做相反的列表,你可以用 -1
在相反的方向旋转,然后先做 %rotate
:
%macro push_multi 1-* ; Accept 1 or more arguments
%rep %0 ; %0 is number of arguments pass to macro
%rotate -1 ; Rotate to the prev argument in the list
; If at beginning of list it wraps to end of list
push %1
%endrep
%endmacro