| III.11.5 Macro Operators There are some special control characters, which are very useful for macro definition, call and expansion:
;; | Macro commentary | Normally, comments in body lines are also contained in the expanded lines. If a commentary begins with ';;' however, it is not stored during macro definition. Therefore, it doesn't consume memory space, and appears in the list file in the macro definition only, but not in the expanded lines.
! | Literal operator | If the escape character '!' precedes another printable character in a macro argument, the assembler is forced to treat that character literally. This means it will be passed to the macro, even if it is a control character, while the literal operator itself is removed.
< > | Literal brackets | If a macro argument is intended to contain separation or control characters, it must be enclosed in literal brackets < ... > to pass it to the macro as one argument string, while the outermost pair of brackets is removed. Literal brackets can be nested to any depth.
% | Evaluation | If a macro argument is preceded by the evaluation operator '%', it is interpreted as an expression, which will be evaluated before it is passed to the macro. The actual argument string will not be the expression itself, but a decimal ASCII representation of its value. The expression must be known on pass 1.
& | Substitution | The '&' character separates parameter names (local symbols) from surrounding text. Outside quoted strings and commentary it serves only as a general separation character. This applies always when a local symbol directly precedes or follows another alphanumeric string. Inside quoted strings and commentary, a local symbol must be preceded by '&' if it is to be substituted there. During every macro expansion, the assembler removes exactly one '&' from every sequence of '&' characters. This allows for example, to define a nested macro inside a macro body, which also uses the substitution operator '&': one writes simply '&&'!
> Example 1: The commentary should only be visible in the definition of the macro LICENSE:
>             LICENSE MACRO
>             DB 'Copyright'  ;;legal stuff
>             ENDM
> When called, the expanded macro body is looking like this in the list file:
>             DB 'Copyright'
> Example 2:
>             SPECIAL !;
> passes a semicolon to the macro SPECIAL as a literal argument. This could also be done with
>             SPECIAL <;>
> Example 3: The macro CONST defines a 16-bit constant in ROM:
>             CONST MACRO NUMB
>             DW NUMB
>             ENDM
> If it is called as shown below,
>             CONST 0815H+4711-42
> the parameter NUMB would be substituted as follows:
>             DW 0815H+4711-42
> If the same macro argument is preceded by a '%' however,
>             CONST %0815H+4711-42
> the substitution will result in:
>             DW 6738
> Example 4: During substitution, both arguments of the macro CONCAT should form a seamless symbol name:
>             CONCAT MACRO NAM, NUM
>             MOV R3,#0
>     NAM&NUM: DJNZ R3,NAM&NUM
>             ENDM
> When CONCAT is called as follows,
>             CONCAT LABEL, 08
> the parameters NAM and NUM are substituted during macro expansion as shown below:
>             MOV R3,#0
>     LABEL08: DJNZ R3,LABEL08