The structure of a macro definition consists of a name, some optional arguments, the body of the macro and a termination keyword. The syntax you use to define a macro is:

##### Syntax

> name MACRO arg1, arg2, ... , argn
> macro-body
> ENDMACRO | ENDM

The name of the macro has the same requirements as a label name (in particular it must start in column one). The arguments are a comma-separated list of identifiers. The body of the macro can have arbitrary assembly language text including other macro definitions and invocations, conditional and file inclusion directives. A macro is instantiated by using its name together with optional actual argument values. A macro instantiation has to occur on its own line—it cannot be used within an expression or as an argument to an assembly code mnemonic or directive. The syntax you use invoke a macro is

##### Syntax

> name actual1, actual2, ... , actualn // comment

When a macro is instantiated the macro body is inserted into the assembly text with the actual values replacing the arguments that were in the body of the macro definition.

##### Example

add MACRO N,a,b,c
load a, N
load b, N
addn , N
pop N
store c,N
ENDMACRO

longlong MACRO name, storage
name storage BYTE[8]
ENDMACRO
longlong A, STATIC
longlong B, STATIC
longlong C, STATIC
.......
add 8, A, B, C // C = A + B

This example shows two macro definitions: add which defines a code sequence that will add two variables and store the result in a third variable; and longlong defines an 8-byte variable.

## Labels in macros

When labels are used in macros they must be unique for each instantiation to avoid duplicate label definition errors. The assembler provides a label generation mechanism for situations where the label name isn’t significant and a mechanism for constructing specific label names.

If a macro definition contains a jump to other instructions in the macro definition it is likely that the actual name of the label isn’t important. To facilitate this a label of the form name? can be used.

##### Example

incifeq MACRO a, N
pushw N
load a
cmpn ,2
bne NE?
incn a
NE?
ENDMACRO

var1 STATIC WORD = 10
incifeq var1, 10 // var1 is 11
incifeq var1, 10 // var1 is still 11

This example defines a macro incifeq that will increment a variable only if the variable has a specific value. If the label in the macro didn’t use a ’?’ then the assembler would have produced an error that the label was defined multiple times.

There are situations when a macro invocation should result in the definition of a label. In the simplest case the label can be passed as an argument to the macro, however there are cases when the label name should be constructed from other tokens. The macro definition facility provides two constructs to enable this:

- tokens can be concatenated by putting ## between them;
- the value of a constant symbol can be used by prefixing the label with $$.

##### Example

MELBINARYOP macro opcode
_mel##opcode##$$MELNUM
BLOCK
op1? IN WORD
op2? IN WORD
ccr OUT WORD
loadi op1?, $$MELNUM
loadi op2?, $$MELNUM
opcode ,$$MELNUM
pop $$MELNUM
storei op1?,$$MELNUM 45
prim 0x5
store ccr,1
RETURN
ENDMACRO
MELNUM SET 3
MELBINARYOP addn
MELNUM SET MELNUM+1
MELBINARYOP addn
In this example the macro will define a function whose name is based on a macro argument and the value of the label MELNUM the macro invocations will create the functions _meladdn3 and _meladdn4.

## Loops

If multiple definitions are required a loop structure can be used. This can be achieved either by a recursive macro definitions or by the use of the LOOP directive.

##### Example

MKMELARITH macro N
IF N
MKMELARITH (N-1)
MELNUM SET MELNUM+1
MELBINARYOP addn
ENDIF
ENDMACRO
MKMELARITH 10

This example will produce functions _meladdn10 ... _meladdn1.

If the loop counter is a large number then a recursive macro may consume considerable machine resources. To avoid this we recommend using the LOOP directive, which is an iterative rather than recursive solution.

##### Syntax

LOOP expression
loop-body
ENDLOOP

The loop control expression must be a compile time constant. The loop body can contain any assembly text (including further loop constructs) except macro definitions (since it would result in multiple definitions of the same macro).

##### Example

x set 3
LOOP x
pushb (x*y)
x set x-1
ENDLOOP

This will assemble the instructions pushb 3, pushb 2 and pushb 1. Note that the label naming capabilities (? $$ ##) are not available within the body of a loop. If the loop body is to declare labels then a recursive macro definition should be used or a combination of using macro invocation to define the labels and the loops to define the text of the label.