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 calledcomm
, which takes no arguments..macro plus1 p, p1
or.macro plus1 p p1
– Either statement begins the definition of a macro calledplus1
, 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 calledreserve_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 asreserve_str a,b
(with\p1
evaluating toa
and\p2
evaluating tob
), or asreserve_str ,b
(with\p1
evaluating as the default, in this case0
, and\p2
evaluating tob
).
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