Macro language¶
The .macro directive allows you to generate new commands that can
create assembler output. A simple example follows:
foo .macro a, b
.byte \a
.word \b - 1
.long 0
.endm
This creates a new macro named foo which takes two arguments a and b. To use an argument inside the macro, prefix the parameter name with a backslash \.
Rules for argument substitutions¶
When looking for argument substitutions, the longest match is
favored. This means if you have parameters called a and aa,
substituting the longer name is always tried before shorter names,
ignoring the order the parameters are given. As there is no way to
explicitly specify the end of a parameter name inside the body, a
parameter may accidently try to match characters that comes after the
parameter. A good rule of thumb is to make use of space to separate
entities whenever possible. This also tends to improve readability.
Use of local labels¶
Each macro expansion will create a new unique context for local labels inside the macro body. Any previous local label context is restored after the macro is expanded. Thus, local labels inside a macro will not clash or interfere with any local labels surrounding the use of the macro.
This also works when using nested macro expansions. If a macro uses another macro inside its body, that inner macro expansion will have its own private local label context, and the previous context of the outer macro expansion will be restored when the inner macro has been expanded.
Thus, you are able to do:
waitfield .macro field
1$: c=c-1 \field
gonc 1$
.endm
ldi 100
waitfield x
1$: c=0 w
Which would create the following list file:
###############################################################################
# #
# Calypsi assembler for Hewlett-Packard Nut version 5.16 #
# 14/Apr/2026 16:42:38 #
# Command line: -l macro-local.s #
# #
###############################################################################
0001 waitfield .macro field
0002 1$: c=c-1 \field
0003 gonc 1$
0004 .endm
0005
0006 0000 130064 ldi 100
0007 waitfield x
\ 0002 266 `1$`: c=c-1 x
\ 0003 3fb gonc `1$`
0008 0004 04e 1$: c=0 w
0009
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 5 words
Arguments with comma¶
Arguments to a macro are comma separated. This poses a problem in a
situation where you want an argument to contain a comma character.
The .argdelim directive defines a start and stop character that
can be used to create an argument that contains a comma character.
.argdelim <>
access .macro arg1, arg2
...
.endm
access 0, <2,a>
Here arg1 is bound to 0 and arg2 is bound to the value
2,a.
The delimiter can be either one or two characters and you can pick any suitable character combination. By default there are no delimiter characters defined.
If a single character combination is not suitable, you can use two
characters, e.g. <- and -> which would be defined as follows:
.argdelim <-->
access .macro arg1, arg2
...
.endm
access 0, <-2,a->
All delimiter characters are stripped and arg2 is bound to 2,a
here as well.