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

# zasm - Z80 Assembler – Version 4.4

# Pseudo instructions

[<prev] [next>]

| ### 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: MACROmacro
            <instr>
            ...
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
Alternate syntax:
            .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro <name>
            <instr>
            ...
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
#insert: Examples: #assert: Example: incbin: Examples: #assert: Example:Example:
    counter = 0
        .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro COUNT
    counter = counter + 1
        .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm

        ...
        COUNT
        ...

    final_count Pseudo instructions: equ
    Types of labels: Named values
    Labels: EQUequ 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: MACROmacro <tag><name1> [ , <tag><name2> … ]
            <instr>
            ...
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
Alternate syntax:
            .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro <name> <tag><name1> [ , <tag><name2> … ]
            <instr>
            ...
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
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: MACROmacro A, B         ; 1)
            ld  &A, &B
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm

            .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro foo, A, B    ; 2)
            ld  \A, \B
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm

    foo:    .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro &A, &B       ; 3)
            ld  &A, &B
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm

            .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro foo, %A, %B  ; 4)
            ld  %A, %B
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
##### 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: Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACRO macro is defined as `<name> Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro <arguments…>` then the tag is '&'. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACRO macro is defined as `Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro <name> <arguments…>` then the tag is '\'. 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: MACROmacro &A
            ld  b,&A
    foo&A:  ld  a,' '       ; <-- simple unique Pseudo instructions: Label definition
    Numeric expressions: Labels
    8080 Assembler: Labelslabel name
            rst 8
            djnz    foo&A
            Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm

            ...
            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.
    .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro foo_define &NAME, &rr
            ld_&NAME_&rr = ld_int_&rr
    .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
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: MACROMACRO WHERE
          Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBDB    (WHERE >> 8) + 128
          Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBDB    WHERE & 0FFH
          Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmENDM
##### 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. Use redefinable Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels labels instead which are defined with 'defl', '=' or 'Pseudo instructions: defl, set and '=' Labels: SET set' or use a Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local context between '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local' and '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal endlocal' (since version 4.4.6) or construct unique Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label names using a redefinable counter and text replacement with '{…}'. ##### Literal text replacement of expressions between '{' and '}' Expressions 8080 Assembler: Expressions Expressions between '{' and '}' are evaluated and immediately replaced with the result Since version 4.2.6 in Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACRO macros Since version 4.4.6 everywhere #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:Example:
    cnt:    .Pseudo instructions: equ
    Types of labels: Named values
    Labels: EQUequ  0         ; initialize redefinable Pseudo instructions: Label definition
    Numeric expressions: Labels
    8080 Assembler: Labelslabel 'cnt'

    ; calculate unsigned max
    ; &A = umax(&A,&B)
    ; usable for a and hl.

    umax:   .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro &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: EQUequ  cnt+2     ; next Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro call will use L2 and L3 and so on
            .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
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: EQUequ 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: MACROmacro Foo
    cnt = cnt+1
    L{cnt}: .Pseudo instructions: defw, dw, .dw, .word
    8080 pseudo instructions: DWdw cnt ; 1)
    cnt = cnt+1
    L{cnt}: .Pseudo instructions: defw, dw, .dw, .word
    8080 pseudo instructions: DWdw cnt ; 2)
    .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro
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: Reference to arguments without a tag character Keyword 'Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local' before a <NAME> to define a single Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label: try to use 'defl'. since version 4.4.6: use a Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local context: '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local' … '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal endlocal' |

[<prev] [top] [next>]