Lesson 2 of 10

Hello, World!

You'll write, assemble, link and run a program that prints Hello, World!. Along the way you'll see the system call that higher-level languages normally hide from you.

To print text, we make a `write` system call directly to the Linux . A syscall is the mechanism for asking the OS to do something on your behalf — write to , read a file, allocate . We load the syscall number into rax and into rdi, rsi, rdx, then execute the `syscall` instruction.

x86-64 assembly
; hello.asm — x86-64 Linux NASM
; Assemble: nasm -f elf64 hello.asm -o hello.o
; Link:     ld hello.o -o hello
; Run:      ./hello

section .data
    msg db "Hello, World!", 10   ; 10 = newline (\n)
    len equ $ - msg              ; $ = current address, so len = length of msg

section .text
    global _start                ; expose _start as entry point to linker

_start:
    ; sys_write(fd=1, buf=msg, count=len)
    mov rax, 1          ; syscall number: 1 = write
    mov rdi, 1          ; file descriptor: 1 = stdout
    mov rsi, msg        ; pointer to the string
    mov rdx, len        ; number of bytes to write
    syscall             ; make the kernel call

    ; sys_exit(status=0)
    mov rax, 60         ; syscall number: 60 = exit
    mov rdi, 0          ; exit code 0 = success
    syscall
Bash
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello
# Hello, World!

# See the object file's symbols:
nm hello.o

# Disassemble to verify:
objdump -d hello
Finished reading?Mark it done to track your progress.

Tip: use the ← and → keys to move between lessons.