What is a Macro?
A macro is a sequence of instructions or data definitions that you define once and can then reuse multiple times throughout your code by simply typing the macro’s name. When the assembler encounters the macro name, it substitutes the entire predefined block of code in its place.
Macro vs. Subroutine:
- Subroutine (
CALL
): Saves memory by running one copy of the code, but is slower because it incurs the overhead of theCALL
andRET
instructions (17 cycles). - Macro: Faster because the code is pasted directly (inline) every time it’s used, but increases the size of the assembled program.
Defining a Simple Macro
The syntax for defining a macro varies slightly between assemblers (e.g., TASM, Z80Asm, sjasmplus), but they typically use MACRO
and ENDM
or DEFM
.
Example: A Custom 16-bit Load Macro
This macro creates a reusable command called LDRR
that simplifies loading a 16-bit value into any 16-bit register pair (DE
, HL
, or BC
). The %1
and %2
are parameters supplied by the user.
DEFM LDRR #1, #2 ; Define Macro LDRR with two parameters
LD #1, #2 ; Actual instruction sequence
ENDM ; End of macro definition
; --- Usage ---
START:
LDRR DE, 5000H ; Macro call
LDRR HL, START_ADDRESS ; Macro call
; The assembler expands the code as:
; LD DE, 5000H
; LD HL, START_ADDRESS
Macros for Complex Tasks
Macros become powerful when they hide complex, multi-line logic behind a simple command.
Example: The Safe Stack-Swap Macro
This macro quickly swaps the contents of two register pairs (HL
and DE
) without overwriting memory outside the stack.
DEFM SWAP_HLDE
PUSH HL ; Save HL
PUSH DE ; Save DE
POP HL ; HL gets DE's original value
POP DE ; DE gets HL's original value
ENDM
; --- Usage ---
SWAP_HLDE ; Swaps the contents of HL and DE in 4 instructions
Debugging Macros: Always check your assembler’s listing file (if available). The listing file shows the original source code alongside the expanded machine code, which is essential for catching errors in your macro logic.