|
'.Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro' starts a Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro definition and '.Pseudo instructions: macro, .macro, endm and .endm Pseudo instructions: rept, .rept, endm and .endmendm' Pseudo instructions: end, .end 8080 pseudo instructions: ENDends it. Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROMacros 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: MACROmacro 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.
<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, endifif your source happens to be a Forth interpreter. It uses a redefinable Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel which is redefined every time the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro is used in the source. The final value of the redefinable Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel is only really the final value at the Pseudo instructions: end, .end 8080 pseudo instructions: ENDend of your source. In order to use it before the last occurance of the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro, it is finally copied into another Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel named 'final_count' which can be used everywhere in the source.
<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
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: MACROmacro 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, endifIf the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro 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, endifIf the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro 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, endifif 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: Labelslabel 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: Labelslabel.
.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
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: ENDend at the next comma, semicolon or line Pseudo instructions: end, .end 8080 pseudo instructions: ENDend. 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: ENDend. 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: MACROmacro. It is also helpful Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif you need to pass spaces at the start or Pseudo instructions: end, .end 8080 pseudo instructions: ENDend 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: MACROmacro arguments. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf you mix this with the complex argument style then you can probably run into interesting problems. B-)
Frequently you need some Types of labels: Program labels Types of labels: Program labelsprogram labels in a Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro, but Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif you use a Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro more than once then you'll have multiple definitions of this Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel name and assembly fails.
- Use redefinable Pseudo instructions: Label definition
Numeric expressions: Labels 8080 Assembler: Labelslabels instead which are defined with 'defl', '=' or 'Pseudo instructions: defl, set and '=' Labels: SETset'
- 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 .endlocallocal context between '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocallocal' and '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocalendlocal' (since version 4.4.6)
- or construct unique Pseudo instructions: Label definition
Numeric expressions: Labels 8080 Assembler: Labelslabel names using a redefinable counter and text replacement with '{…}'.
Expressions 8080 Assembler: ExpressionsExpressions 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: 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: MACROmacro replacement. This had a subtle side effect: All Expressions 8080 Assembler: Expressionsexpressions between '{' and '}' were already evaluated before the lines from the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro were assembled. Therefore redefinitions of Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabels performed inside the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro had no effect on '{…}' Expressions 8080 Assembler: Expressionsexpressions until the Pseudo instructions: end, .end 8080 pseudo instructions: ENDend of the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro. 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: Expressionsexpressions between '{' and '}' even Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif this line was the very first in the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro; but it would have effected all other normal Expressions 8080 Assembler: Expressionsexpressions in the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro 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: Expressionsexpression 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: Labelslabel in line 1) would still be 'L0' while the value stored with '.Pseudo instructions: defw, dw, .dw, .word 8080 pseudo instructions: DWdw' would be 1. In line 2) the Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel again would still be 'L0' (and assembly fails) while the value stored with '.Pseudo instructions: defw, dw, .dw, .word 8080 pseudo instructions: DWdw' 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: Labelslabel names are 'L1' and 'L2' as expected.
It is possible to conditionally exclude portions of the Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro by use of the Pseudo instructions 8080 Assembler: 8080 pseudo instructionspseudo instructions '.Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif', '.else' and '.Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifendif'. (do not use '#if' and '#endif'!)
Assembler directives (starting with '#') inside Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacros are possible but deprecated.
Also, you should not use '#' for your argument tag.
Since version 4.4.6 Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro dfinitions inside Pseudo instructions: macro, .macro, endm and .endm 8080 pseudo instructions: MACROmacro definitions are possible and may make some sense with text replacement between '{' and '}'. But you really should know what you are doing!
- 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 .endlocallocal' 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 .endlocallocal Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel: 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 .endlocallocal context: '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocallocal' … '.Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocalendlocal'
| |