Macros And Defining Values With EQU In Assembly
Macros
A macro is a single instruction that expands into a predefined set of instructions to perform a particular task.
Why Use Macros?
Imagine writing the same sequence of instructions for different memory locations or registers. Macros eliminate this redundancy, making your code cleaner and easier to maintain. Here are some key advantages of macros:
- Reduced Code Size: By using a single macro for repeated code blocks, you shrink your assembly file size.
- Improved Readability: Macros enhance code readability by encapsulating complex operations under meaningful names.
- Error Reduction: Defining a macro ensures consistency and reduces the risk of typos in repeated code sections.
- Flexibility: Macros allow for parameterized instructions, adapting the code based on arguments passed during invocation.
Defining Macros
1. Single Line Macros
Defined using the %define
directive, these macros expand to a single instruction or expression when used.
%define SQUARE(x) ((x) * (x))
mov eax, SQUARE(5) ; Expands to mov eax, 25
2. Multi-Line Macros
Defined with %macro
and %endmacro
directives, these macros encompass a block of instructions that execute when called.
%macro exit 0
mov rax, SYS_EXIT
mov rdi, 0
syscall
%endmacro
structure:
%macro <name> <argc>
...
<macro body>
...
%endmacro
Macro Parameters:
Both types of macros can accept parameters, allowing you to customize the code during invocation. Parameters are represented by dollar signs
($)
Defining Values With EQU
The EQU
directive essentially assigns a symbolic name (label) to a constant value. This value can be a number, a string, or even an expression. Unlike data directives like DB (define byte) or DW (define word), EQU
doesn't reserve memory space. Instead, it acts as a placeholder,
Structure
<name> equ <value>
Demo:
SYS_READ equ 0
SYS_WRITE equ 1
SYS_EXIT equ 60
Simple program using macros and EQU
STDIN equ 0
STDOUT equ 1
STDERR equ 2
SYS_READ equ 0
SYS_WRITE equ 1
SYS_EXIT equ 60
section .data
digit db 0,10
section .text
global _start
%macro exit 0
mov rax, SYS_EXIT
mov rdi, 0
syscall
%endmacro
%macro printdigit 1
mov rax, %1
call _printraxdigit
%endmacro
_start:
printdigit 49
printdigit 50
exit
_printraxdigit:
;mov rax, 50
mov [digit], al
mov rax, SYS_WRITE
mov rdi, STDOUT
mov rsi, digit
mov rdx, 2
syscall
ret