as: Macro

 
 7.61 '.macro'
 =============
 
 The commands '.macro' and '.endm' allow you to define macros that
 generate assembly output.  For example, this definition specifies a
 macro 'sum' that puts a sequence of numbers into memory:
 
              .macro  sum from=0, to=5
              .long   \from
              .if     \to-\from
              sum     "(\from+1)",\to
              .endif
              .endm
 
 With that definition, 'SUM 0,5' is equivalent to this assembly input:
 
              .long   0
              .long   1
              .long   2
              .long   3
              .long   4
              .long   5
 
 '.macro MACNAME'
 '.macro MACNAME MACARGS ...'
      Begin the definition of a macro called MACNAME.  If your macro
      definition requires arguments, specify their names after the macro
      name, separated by commas or spaces.  You can qualify the macro
      argument to indicate whether all invocations must specify a
      non-blank value (through ':'req''), or whether it takes all of the
      remaining arguments (through ':'vararg'').  You can supply a
      default value for any macro argument by following the name with
      '=DEFLT'.  You cannot define two macros with the same MACNAME
      unless it has been subject to the '.purgem' directive (See
      Purgem) between the two definitions.  For example, these are all
      valid '.macro' statements:
 
      '.macro comm'
           Begin the definition of a macro called 'comm', which takes no
           arguments.
 
      '.macro plus1 p, p1'
      '.macro plus1 p p1'
           Either statement begins the definition of a macro called
           'plus1', which takes two arguments; within the macro
           definition, write '\p' or '\p1' to evaluate the arguments.
 
      '.macro reserve_str p1=0 p2'
           Begin the definition of a macro called 'reserve_str', with two
           arguments.  The first argument has a default value, but not
           the second.  After the definition is complete, you can call
           the macro either as 'reserve_str A,B' (with '\p1' evaluating
           to A and '\p2' evaluating to B), or as 'reserve_str ,B' (with
           '\p1' evaluating as the default, in this case '0', and '\p2'
           evaluating to B).
 
      '.macro m p1:req, p2=0, p3:vararg'
           Begin the definition of a macro called 'm', with at least
           three arguments.  The first argument must always have a value
           specified, but not the second, which instead has a default
           value.  The third formal will get assigned all remaining
           arguments specified at invocation time.
 
           When you call a macro, you can specify the argument values
           either by position, or by keyword.  For example, 'sum 9,17' is
           equivalent to 'sum to=17, from=9'.
 
      Note that since each of the MACARGS can be an identifier exactly as
      any other one permitted by the target architecture, there may be
      occasional problems if the target hand-crafts special meanings to
      certain characters when they occur in a special position.  For
      example, if the colon (':') is generally permitted to be part of a
      symbol name, but the architecture specific code special-cases it
      when occurring as the final character of a symbol (to denote a
      label), then the macro parameter replacement code will have no way
      of knowing that and consider the whole construct (including the
      colon) an identifier, and check only this identifier for being the
      subject to parameter substitution.  So for example this macro
      definition:
 
           	.macro label l
           \l:
           	.endm
 
      might not work as expected.  Invoking 'label foo' might not create
      a label called 'foo' but instead just insert the text '\l:' into
      the assembler source, probably generating an error about an
      unrecognised identifier.
 
      Similarly problems might occur with the period character ('.')
      which is often allowed inside opcode names (and hence identifier
      names).  So for example constructing a macro to build an opcode
      from a base name and a length specifier like this:
 
           	.macro opcode base length
                   \base.\length
           	.endm
 
      and invoking it as 'opcode store l' will not create a 'store.l'
      instruction but instead generate some kind of error as the
      assembler tries to interpret the text '\base.\length'.
 
      There are several possible ways around this problem:
 
      'Insert white space'
           If it is possible to use white space characters then this is
           the simplest solution.  eg:
 
                	.macro label l
                \l :
                	.endm
 
      'Use '\()''
           The string '\()' can be used to separate the end of a macro
           argument from the following text.  eg:
 
                	.macro opcode base length
                        \base\().\length
                	.endm
 
      'Use the alternate macro syntax mode'
           In the alternative macro syntax mode the ampersand character
           ('&') can be used as a separator.  eg:
 
                	.altmacro
                	.macro label l
                l&:
                	.endm
 
      Note: this problem of correctly identifying string parameters to
      pseudo ops also applies to the identifiers used in '.irp' (See
      Irp) and '.irpc' (SeeIrpc) as well.
 
 '.endm'
      Mark the end of a macro definition.
 
 '.exitm'
      Exit early from the current macro definition.
 
 '\@'
      'as' maintains a counter of how many macros it has executed in this
      pseudo-variable; you can copy that number to your output with '\@',
      but _only within a macro definition_.
 
 'LOCAL NAME [ , ... ]'
      _Warning: 'LOCAL' is only available if you select "alternate macro