Macros in Nasm x86-64

Rawley AmankwahRawley Amankwah
3 min read

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.

0
Subscribe to my newsletter

Read articles from Rawley Amankwah directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rawley Amankwah
Rawley Amankwah