Macros in Nasm x86-64

Macros are relatively easy to implement in Nasm x86-64. Without much ado, let us head straight to it.
We have already seen how to print “Hello World” in Nasm x64.
; Print Hello World to screen in Nasm x64
section .data
msg db "Hello World!", 0, 10 ; String with null (0) and newline (10)
msglength equ $ - msg ; msglength = len(msg) i.e calculates length of string
section .text
global _start ; entry point of program
_start:
; Print msg
mov rax, 1 ; sys_write
mov rdi, 1 ; file descriptor: stdout
mov rsi, msg ; pointer to msg
mov rdx, msglength ; length of msg
syscall ; ask kernel to print msg
_exit:
mov rax, 60 ; sys_exit
mov rdi, 0 ; return value 0 akin to exit(0) in C or System.exit(0) in Java
syscall ; please kernel, exit nicely
But it can get tedious to write out the print, and the exit portions of the code if there are multiple prints to standard out and different exit return values needed. That is where macros come in.
In our directory, we create a file called mymacros.inc . This file will contain our macros.
%macro print 2
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, %1 ; pointer to string
mov rdx, %2 ; length
syscall
%endmacro
%macro exit 1
mov rax, 60
mov rdi, %1
syscall
%endmacro
Explanation
Macros are like header files in C or external functions in other higher level programming languages which we can invoke in our program. Macros have its syntax beginning with %macro and ending with %endmacro. In between, we have the macro name and then the number of “parameters”. And finally, we have the macro body.
%macro macro_name "number of parameters"
macro_body
%endmacro
In our example above, print is the macro_name, 2 is the number of parameters, and %1 and %2 refers to the parameters themselves. The same idea extends to the exit macro. Note that to invoke macro usage in your program, you will need to add %include “mymacros.inc” at the top of your program. So that our Hello World program will look like
; Print Hello World to screen in Nasm x64
%include "mymacros.inc"
section .data
msg db "Hello World!", 0, 10 ; String with null (0) and newline (10)
msglength equ $ - msg ; msglength = len(msg) i.e calculates length of string
section .text
global _start ; entry point of program
_start:
print msg, msglength
exit 0
This looks clean, does it not? Macros come in real handy when writing assembly programs. We shall discuss more about macros rules in the future. Until then, try the exercise below.
Macro Exercise
Implement the user input routine as a macro.
Subscribe to my newsletter
Read articles from Rawley Amankwah directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
