<--  back   Last regenerated: 2022-04-20 17:31:36 kio

zasm - Z80 Assembler – Version 4.4

Pseudo instructions

macro, .macro, endm and .endm

'.Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro' starts a Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro definition and '.Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm' Pseudo instructions: end, .end
8080 pseudo instructions: END
ends it. Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
Macros are assigned a name by which they can later be used at the place of an ordinary instruction to insert the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro body.

There are quite numerous formats used by different assemblers and zasm tries to support at least some of them out of the box. In the following code examples the instruction names with or without a dot can be used interchangeably.

Define a simple macro without arguments
<name>  .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro <instr> ... .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm

Alternate syntax:

        .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro <name> <instr> ... .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm

#insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
Example:

counter = 0
    .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro COUNT counter = counter + 1 .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm   ... COUNT ...   final_count Pseudo instructions: equ
Types of labels: Named values
Labels: EQU
equ counter

This defines a counter for something, e.g. Forth words Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if your source happens to be a Forth interpreter. It uses a redefinable Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label which is redefined every time the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro is used in the source. The final value of the redefinable Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label is only really the final value at the Pseudo instructions: end, .end
8080 pseudo instructions: END
end of your source. In order to use it before the last occurance of the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro, it is finally copied into another Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label named 'final_count' which can be used everywhere in the source.

Define a macro with arguments
<name>  .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro <tag><name1> [ , <tag><name2> … ] <instr> ... .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm

Alternate syntax:

        .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro <name> <tag><name1> [ , <tag><name2> … ] <instr> ... .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm

Invocation:

        <name> <some text> [ , <some text> … ]

This defines a macro with some arguments. Either of both definition styles are possible. Additionally there are different methods for defining and referencing the symbol arguments:

foo:    .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro A, B ; 1) ld &A, &B .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm   .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro foo, A, B ; 2) ld \A, \B .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm   foo: .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro &A, &B ; 3) ld &A, &B .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm   .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro foo, %A, %B ; 4) ld %A, %B .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm
Argument processing in the macro definition

A special character, a 'tag', should be preprended to the argument names in the head and body. This 'tag' varies from assembler to assembler. zasm treats any non-letter character at start of the argument names as this 'tag'. Most commonly used is '&'.

Some assemblers required the tag only in the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro body, not in the head, see version 1) and 2) in the above #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example. zasm supports this "as seen in source #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
examples" in the following way:

Also, the tag is not required in the body Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if it was not written in the argument list. Then argument references must be full words, whereas with tag they are also detected as part of a words.

The use of '&' is recommended. All other tags are to support various sources out of the box only!

#insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
Example:

foo:    Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro &A ld b,&A foo&A: ld a,' ' ; <-- simple unique Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label name rst 8 djnz foo&A Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm   ... foo 20 ... foo 8

In this #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example the argument is used as the second argument for 'ld b,N' and to construct a unique Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label name for each invocation. Another solution would have been to use a counter and a redefinable Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label.

.macro foo_define &NAME, &rr
        ld_&NAME_&rr = ld_int_&rr
.Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm

In this #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example '&NAME' in 'ld_&NAME_&rr' is also replaced, though 'NAME' is only the first 4 characters of the potential 5-letter name 'NAME_'.

An #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example without tag character:

DWA:  Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
MACRO WHERE Pseudo instructions: defb, db, .db and .byte
8080 pseudo instructions: DB
DB (WHERE >> 8) + 128 Pseudo instructions: defb, db, .db and .byte
8080 pseudo instructions: DB
DB WHERE & 0FFH Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
ENDM
Argument processing in the macro invocation

There are two methods for argument parsing, the standard 'clean & simple' one, and one for complex arguments.

Standard arguments

Arguments must follow the basic syntax rules: strings or character literals must be closed (balanced delimiters) and arguments Pseudo instructions: end, .end
8080 pseudo instructions: END
end at the next comma, semicolon or line Pseudo instructions: end, .end
8080 pseudo instructions: END
end. Brackets are not required to match.

    foo a, 1+2, a*(1+2)
    foo (, "hi, i'm Kio!", )    ; 3 arguments

Complex arguments

Complex arguments start with an opening '<' and run up to the next '>' which is followed by a comma, a semicolon or the line Pseudo instructions: end, .end
8080 pseudo instructions: END
end. With the help of the angle brackets you can pass unbalanced ''' and '"' or a comma or a semicolon as one argument to a Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro. It is also helpful Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if you need to pass spaces at the start or Pseudo instructions: end, .end
8080 pseudo instructions: END
end of an argument, or even just a space.

    foo <,>, <;>, <">           ; 3 arguments: , ; and "
    foo <<>, < >, <ld a,b>      ; 3 arguments: < space and ld a,b
    foo >, ><,                  ; 3 arguments: > >< and nothing

There are still some impossible combinations, e.g. it is not possible to pass <>, (3 characters) as an argument.

'{...}' replacement

Since version 4.4.6 numeric expressions between '{' and '}' are evaluated and immediately replaced with the resulting text. This also happens for Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro arguments. Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
If you mix this with the complex argument style then you can probably run into interesting problems. B-)

Labels in macros

Frequently you need some Types of labels: Program labels
Types of labels: Program labels
program labels in a Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro, but Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if you use a Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro more than once then you'll have multiple definitions of this Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label name and assembly fails.

Literal text replacement of expressions between '{' and '}'

Expressions
8080 Assembler: Expressions
Expressions between '{' and '}' are evaluated and immediately replaced with the result

#insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
Example:

cnt:    .Pseudo instructions: equ
Types of labels: Named values
Labels: EQU
equ 0 ; initialize redefinable Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label 'cnt'   ; calculate unsigned max ; &A = umax(&A,&B) ; usable for a and hl.   umax: .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro &A, &B and a sbc &A,&B jr nc,L{cnt} ld &A,&B jr L{cnt+1} L{cnt}: add &A,&B L{cnt+1}: cnt .Pseudo instructions: equ
Types of labels: Named values
Labels: EQU
equ cnt+2 ; next Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro call will use L2 and L3 and so on .Pseudo instructions: macro, .macro, endm and .endm
Pseudo instructions: rept, .rept, endm and .endm
endm

Difference between version 4.2.6 and 4.4.6:

Since version 4.2.6 the text replacement was done at the point of the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro replacement. This had a subtle side effect:
All Expressions
8080 Assembler: Expressions
expressions between '{' and '}' were already evaluated before the lines from the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro were assembled. Therefore redefinitions of Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
labels performed inside the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro had no effect on '{…}' Expressions
8080 Assembler: Expressions
expressions until the Pseudo instructions: end, .end
8080 pseudo instructions: END
end of the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro.
So in the above #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example the line cnt .Pseudo instructions: equ
Types of labels: Named values
Labels: EQU
equ cnt+2
had no effect on the Expressions
8080 Assembler: Expressions
expressions between '{' and '}' even Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if this line was the very first in the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro; but it would have effected all other normal Expressions
8080 Assembler: Expressions
expressions in the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro as expected. (in the above #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example there is none except in the cnt incrementing Expressions
8080 Assembler: Expressions
expression itself.)

cnt = 0
.Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro Foo cnt = cnt+1 L{cnt}: .Pseudo instructions: defw, dw, .dw, .word
8080 pseudo instructions: DW
dw cnt ; 1) cnt = cnt+1 L{cnt}: .Pseudo instructions: defw, dw, .dw, .word
8080 pseudo instructions: DW
dw cnt ; 2) .Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro

In this #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example the Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label in line 1) would still be 'L0' while the value stored with '.Pseudo instructions: defw, dw, .dw, .word
8080 pseudo instructions: DW
dw' would be 1.
In line 2) the Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label again would still be 'L0' (and assembly fails) while the value stored with '.Pseudo instructions: defw, dw, .dw, .word
8080 pseudo instructions: DW
dw' would be 2. This was irritating and is no longer the case since version 4.4.6.

Since version 4.4.6 text replacements between '{' and '}' are now possible everywhere in the source and they are done when the lines are actually assembled. Now in the above #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example the Pseudo instructions: Label definition
Numeric expressions: Labels
8080 Assembler: Labels
label names are 'L1' and 'L2' as expected.

conditional assembly with '.if' in macros

It is possible to conditionally exclude portions of the Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro by use of the Pseudo instructions
8080 Assembler: 8080 pseudo instructions
pseudo instructions '.Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if', '.else' and '.Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
endif'. (do not use '#if' and '#endif'!)

Assembler directives in macros

Assembler directives (starting with '#') inside Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macros are possible but deprecated.

Also, you should not use '#' for your argument tag.

Nested macro definitions

Since version 4.4.6 Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro dfinitions inside Pseudo instructions: macro, .macro, endm and .endm
8080 pseudo instructions: MACRO
macro definitions are possible and may make some sense with text replacement between '{' and '}'. But you really should know what you are doing!

Not implemented:

Valid HTML   Valid CSS