Copyright (C) 2000-2012 |
GNU Info (nasm.info)Section 4.3.64.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 |