Copyright (C) 2000-2012 |
GNU Info (nasm.info)Section 4.7.54.7.5. Example Use of the Context Stack: Block IFs -------------------------------------------------- This example makes use of almost all the context-stack features, including the conditional-assembly construct `%ifctx', to implement a block IF statement as a set of macros. %macro if 1 %push if j%-1 %$ifnot %endmacro %macro else 0 %ifctx if %repl else jmp %$ifend %$ifnot: %else %error "expected `if' before `else'" %endif %endmacro %macro endif 0 %ifctx if %$ifnot: %pop %elifctx else %$ifend: %pop %else %error "expected `if' or `else' before `endif'" %endif %endmacro This code is more robust than the `REPEAT' and `UNTIL' macros given in *Note Section 4.7.2::, because it uses conditional assembly to check that the macros are issued in the right order (for example, not calling `endif' before `if') and issues a `%error' if they're not. In addition, the `endif' macro has to be able to cope with the two distinct cases of either directly following an `if', or following an `else'. It achieves this, again, by using conditional assembly to do different things depending on whether the context on top of the stack is `if' or `else'. The `else' macro has to preserve the context on the stack, in order to have the `%$ifnot' referred to by the `if' macro be the same as the one defined by the `endif' macro, but has to change the context's name so that `endif' will know there was an intervening `else'. It does this by the use of `%repl'. A sample usage of these macros might look like: cmp ax,bx if ae cmp bx,cx if ae mov ax,cx else mov ax,bx endif else cmp ax,cx if ae mov ax,cx endif endif The block-`IF' macros handle nesting quite happily, by means of pushing another context, describing the inner `if', on top of the one describing the outer `if'; thus `else' and `endif' always refer to the last unmatched `if' or `else'. automatically generated by info2www version 1.2.2.9 |