Assembler Commands - Macro
A macro is a user declared sequence of instructions. When a
macro is invoked the code contained in the macro is inserted into the program in
place of the macro invocation. Unlike a subroutine, a macro does not exist as
code until it is invoked and then the code is inserted into the program. Each macro
must be defined by a unique name. Once a macro is defined the code that it
contains may be inserted into a program by using the macro name in the assembly
source in the same way an instruction or opcode would be used. The macro
definition should appear in the code before it is invoked. Calling macros that
are defined later in the code may result in an error if the macro call is
between a branching instruction and its destination label. The error message:
ERROR: Address or value of symbol has changed during assembly.
See 'Help' on Macros for possible causes
will be displayed if such an error occurs. Placing the macro definitions at the
top of the code will prevent macro calls from causing this error.
Macros are defined using the syntax:
macName MACRO
code
ENDM
Up to thirty-six parameters may be used in the macro as \0 through \9 and \A through \Z. The parameters are specified when the macro is invoked. The assembler replaces the macro argument \n with the parameter specified. Parameter \0 always refers to the .size code letter (B or W or L). Use angle brackets to enclose arguments that contain white space <this is one argument>. See MACRO.X68 in the examples folder for an example.
Example:
OPT MEX
* Convert the ASCII character in \1 to upper case
toUpper MACRO
IFNC \0,B
;if .B not specified
FAIL ERROR: toUpper is .B
only
MEXIT
;exit macro
ENDC
CMP.B #'a',\1
BLO NOT\@
;if not lower case
CMP.B #'z',\1
BHI NOT\@
;if not lower case
SUB.B #$20,\1 ;convert to
upper case
NOT\@
ENDM
START ORG $1000
MOVE.B #'a',D0
toUpper.B D0
;invoke toUpper macro, D0 is parameter \1
MOVE.B #9,D0
TRAP
#15
;Halt Simulator
END START
Labels Within Macros
The \@ directive creates a unique label. The \@ directive should be used to
create labels in macros to avoid having multiple definitions of the same label
when a macro is invoked more than once. The \@ directive may be used in
conjunction with other text to create a descriptive label. The assembler will
replace \@ with a string of the form _n, where n is a unique decimal number.
References to an assembler-generated label always refer to the label of the
given form defined in the current level of macro expansion. Such a label is
referenced as an operand by specifying the same character string as that which
defines the label.
The MEXIT directive
The directive MEXIT may be used to exit macro processing. All
remaining statements in the macro are skipped up to the ENDM directive.
The NARG directive
NARG is a special symbol when referenced within a macro
expansion. The value assigned to NARG is the index of the last argument passed
to the macro in the parameter list (even if nulls). NARG is a reserved word
inside a macro but is undefined outside of macro expansion, and may be
referenced as a user-defined symbol.
In the following example the NARG directive is used to check for the presence of
two arguments. If the macro is called with fewer or more than two arguments an
error is created by using the FAIL directive and the
macro is exited with MEXIT:
MAC
MACRO
IFNE NARG-2
;if not 2 arguments
FAIL ERROR, MAC requires
2 arguments
MEXIT
ENDC
MOVE.\0 \1,D0
CLR.L \2
ENDM
OPT
MEX
START ORG $1000
MAC
#'A'
;causes error 'ERROR, MAC REQUIRES 2 ARGUMENTS'
MAC
#1,D0
MOVE.B #9,D0
TRAP
#15
;Halt Simulator
END
START
Null arguments and Conditional Assembly in Macros
The conditional assembly directive IFxx may be used to test for missing (null) parameters. To assemble conditionally if parameter 1 is null, either of the following directives would be correct:
IFC
'','\1'
or
IFC '\1',''
To assemble conditionally if a parameter is present would use
either of the IFNC formats analogous to the above two.
The condition IFARG may also be used to check for the presence of an argument in a
macro call. The syntax is:
IFARG
n
<statements>
ENDC
Where n specifies the argument (0 - 9, A - Z). If the
specified argument is not present in the macro call the enclosed statements are
not included in the program.
It is possible to specify a null argument in a macro call by an empty string (not a blank) ' ' or empty angle brackets <>. The following listing is a portion of an .L68 file created by EASy68K. Line 7 contains the assembler option MEX to expand macros in the listing file. The macro is named foo and is defined in lines 8 through 14. Line 9 in the macro is using the conditional assembly directive IFC to check for the presence of argument 2. Lines 17m through 36m are macro calls and the expanded macro statements as indicated by the lower case m following the line number. If nested macro calls are made multiple m's are displayed. The macro foo is called on line 17m with 3 arguments. Line 18m shows the result of comparing argument 2 with ' ' was FALSE. Since the result of the IFC conditional statement was false the NOP instruction on line 10 of the macro was not assembled. On line 23m angle brackets <> are used to specify argument 2 is null. Line 24m shows the result of the IFC statement is TRUE and line 25m shows the NOP instruction has been assembled as a result. The same is true on line 30m where an empty string ' ' is used for argument 2.
7 OPT MEX
8 foo MACRO
9 IFC '\2',''
10 nop
11 ENDC
12 move #\1,d0
13 move #\3,d1
14 ENDM
15
16 START
17m foo 1,2,3 no
null argument
FALSE 18m IFC
'2',''
19m ENDC
303C 0001
20m MOVE #1,D0
323C 0003
21m MOVE #3,D1
22m ENDM
23m foo 4,<>,6 argument 2
is null
TRUE 24m IFC
'',''
4E71
25m NOP
26m ENDC
303C 0001
27m MOVE #4,D0
323C 0003
28m MOVE #6,D1
29m ENDM
30m foo 7,'',9 argument 2
is null
TRUE 31m IFC
'',''
4E71
32m NOP
33m ENDC
303C 0001
34m MOVE #7,D0
323C 0003
35m MOVE #9,D1
36m ENDM
37
103C 0009
38 MOVE.B #9,D0
4E4F
39 TRAP #15
Halt Simulator
40
41 END START
Refer to the Examples folder for additional sample code.