5.8.4 Macro Directive

The .macro name [args] and .endm directives allow you to define macros that generate assembly output.

The macro will be called name. If required, it can take arguments when it is used. To allow this, follow the macro name with a list of the argument names with either a space character or comma separating them. A default value can be specified with any argument by following its name with =value.

The following are valid opening lines for macro definitions.
  • .macro comm
 – Begin the definition of a macro called comm, which takes no arguments.
  • .macro plus1 p, p1
or .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).
For example, this definition specifies a macro SUM with two arguments, from and to, that puts a sequence of numbers into memory:
.macro SUM from=0, to=3
.long \from
.if    \+o-\from
SUM "(\from+1)",   \+o
.endif
.endm
The above macro could be used (called), specifying the arguments values, for example, SUM 0,5, which would expand to the following:
.long 0
.long 1
.long 2
.long 3
.long 4
.long 5

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.

The assembler maintains a counter of how many macros it has executed. You can copy that number to the output by using the \@ operator, but only within a macro definition. In the following example, a recursive macro is used to allocate an arbitrary number of labeled buffers.
       .macro make_buffers num,size
BUF\@: .space \size
       .if (\num - 1)
       make_buffers (\num - 1),\size
       .endif
       .endm
       .bss
       # create BUF0..BUF3, 16 bytes each
       make_buffers 4,16
This example macro expands as shown in the following listing.
 6     	       make_buffers (\num - 1),\size
 7     	       .endif
 8     	       .endm 
 9
10     	       .bss
11     	       # create BUF0..BUF3, 16 bytes each
12     	       make_buffers 4,16
12     	> BUF0:.space 16
12 0000 	> .space 16
12     	> .if (4-1)
12     	> make_buffers (4-1),16
12     	>> BUF1:.space 16
12 0010 	>> .space 16
12     	>> .if ((4-1)-1)
12     	>> make_buffers ((4-1)-1),16
12     	>>> BUF2:.space 16
12 0020 	>>> .space 16
12     	>>> .if (((4-1)-1)-1)
12     	>>> make_buffers (((4-1)-1)-1),16
12     	>>>> BUF3:.space 16
12 0030 	>>>> .space 16
12     	>>>> .if ((((4-1)-1)-1)-1)
12     	>>>> make_buffers ((((4-1)-1)-1)-1),16
12     	>>>> .endif
12     	>>> .endif
12     	>> .endif
12     	> .endif