GNU Info

Info Node: (nasm.info)Section 4.7.5

(nasm.info)Section 4.7.5


Next: Section 4.8 Prev: Section 4.7.4 Up: Section 4.7
Enter node , (file) or (file)node

4.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