GNU Info

Info Node: (nasm.info)Section 4.3.6

(nasm.info)Section 4.3.6


Next: Section 4.3.7 Prev: Section 4.3.5 Up: Section 4.3
Enter node , (file) or (file)node

4.3.6. `%rotate': Rotating Macro Parameters
-------------------------------------------

   Unix shell programmers will be familiar with the `shift' shell
command, which allows the arguments passed to a shell script
(referenced as `$1', `$2' and so on) to be moved left by one place, so
that the argument previously referenced as `$2' becomes available as
`$1', and the argument previously referenced as `$1' is no longer
available at all.

   NASM provides a similar mechanism, in the form of `%rotate'. As its
name suggests, it differs from the Unix `shift' in that no parameters
are lost: parameters rotated off the left end of the argument list
reappear on the right, and vice versa.

   `%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.

   So a pair of macros to save and restore a set of registers might
work as follows:

     %macro  multipush 1-*
     
       %rep  %0
             push    %1
       %rotate 1
       %endrep
     
     %endmacro

   This macro invokes the `PUSH' instruction on each of its arguments in
turn, from left to right. It begins by pushing its first argument,
`%1', then invokes `%rotate' to move all the arguments one place to the
left, so that the original second argument is now available as `%1'.
Repeating this procedure as many times as there were arguments
(achieved by supplying `%0' as the argument to `%rep') causes each
argument in turn to be pushed.

   Note also the use of `*' as the maximum parameter count, indicating
that there is no upper limit on the number of parameters you may supply
to the `multipush' macro.

   It would be convenient, when using this macro, to have a `POP'
equivalent, which _didn't_ require the arguments to be given in reverse
order. Ideally, you would write the `multipush' macro call, then
cut-and-paste the line to where the pop needed to be done, and change
the name of the called macro to `multipop', and the macro would take
care of popping the registers in the opposite order from the one in
which they were pushed.

   This can be done by the following definition:

     %macro  multipop 1-*
     
       %rep %0
       %rotate -1
             pop     %1
       %endrep
     
     %endmacro

   This macro begins by rotating its arguments one place to the _right_,
so that the original _last_ argument appears as `%1'. This is then
popped, and the arguments are rotated right again, so the second-to-
last argument becomes `%1'. Thus the arguments are iterated through in
reverse order.


automatically generated by info2www version 1.2.2.9