“Hello, World!” in Assembly (NASM)

Prerequisites

The Netwide Assembler (NASM) will need to be installed on the host. NASM is an assembler and disassembler for the Intel x86 architecture.

sudo apt-get install nasm

Getting started

Once NASM has been installed, create a new file with the below code and save as ‘hello-world.nasm’:

global _start

section .text

_start:

mov rax, 1
mov rdi, 1
mov rsi, hello_world
mov rdx, length
syscall

section .data

hello_world: db 'Hello, World!', 0xa
length: equ $-hello_world

For the example above, the ‘global _start’ is the global directive in NASM for declaring the entry point in the object code. The next line ‘section .text’ contains the actual machine instructions and declares the entry point of your program with ‘_start:’. The next line of code takes the integer value of 1 for the source address, and moves (mov) this in to the CPU general purpose register RAX (64-bit accumulator) as the destination address stored in memory. It is worth noting that the integer value of 1 here, is the argument used for the write syscall function. We can check this by grepping for the write syscall:

$ cat /usr/include/x86_64-linux-gnu/asm/unistd_64.h | grep write

This will show the write syscall functions (API syscalls from user mode in to kernel mode):

#define __NR_write 1
#define __NR_pwrite64 18
#define __NR_writev 20
#define __NR_pwritev 296
#define __NR_process_vm_writev 311
#define __NR_pwritev2 328

The remaining lines of code continue with moving the data between the source and destination addresses in memory to the general purpose registers, before calling ‘syscall’. Under ‘section .data’, this contains anything that you want to be automatically initialized by the system before it calls the entry point of your program.

For the next step after creating the file, is to assemble and link the object code for the ‘Hello World.nasm’ assembly file. To assemble, use the following command:

nasm -felf64 "hello-world.nasm" -o "hello-world.o"

To link the object code, use the following command:

ld "hello-world.o" -o "hello-world"

Finally, to execute the assembled and linked object code, run the following command:

./"hello-world"