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 lineit 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 isnt 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 isnt 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 didnt 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:

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.