Belajar Assembly - Instalasi & Hello World
Episode 3 of 23

Belajar Assembly - Instalasi & Hello World

Momen pertama menulis kode assembly: memastikan NASM terinstall, menyusun program Hello World Linux x86-64 paling sederhana memakai syscall write(1, msg, len) dan exit(0), lalu assemble dengan nasm -f elf64 dan link dengan ld, hingga memverifikasi eksekusi dan belajar membaca error assembler.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Semua fondasi sudah berdiri: toolchain di episode 0, sejarah di episode 1, dan arsitektur CPU di episode 2. Sekarang saatnya momen yang ditunggu — menulis program assembly pertama dan melihat hasilnya tercetak di terminal. Program ini bukan sekadar "Hello World": ia memperkenalkan tiga konsep inti yang akan menemani kita sepanjang series: syscall, section, dan label.

Episode 3 juga menandai transisi dari teori ke praktik. Kalian akan merasakan siklus yang akan kalian ulangi ratusan kali: tulis → assemble → link → jalankan → debug. Mari kita mulai.

Memastikan NASM Terinstall

Jika sudah menyelesaikan episode 0, NASM seharusnya sudah siap. Verifikasi cepat:

Cek versi NASM
nasm -v

Outputnya berbentuk NASM version 3.02 ... atau setidaknya 2.16.x. Jika belum ada, install sesuai distro:

Install NASM
sudo apt install nasm    # Debian/Ubuntu
sudo dnf install nasm    # RHEL/Fedora
brew install nasm        # macOS

Anatomi Program Hello World

Buat file hello.asm di ~/asm-lab/src:

hello.asm
section .data
    msg db "Hello, World!", 0x0a
    len equ $-msg
 
section .text
    global _start
 
_start:
    mov rax, 1          ; syscall number untuk write = 1
    mov rdi, 1          ; fd pertama = stdout
    mov rsi, msg        ; alamat buffer yang berisi pesan
    mov rdx, len        ; panjang buffer
    syscall
 
    mov rax, 60         ; syscall number untuk exit = 60
    mov rdi, 0          ; exit code = 0 (sukses)
    syscall

Section .data: Tempat Data

Baris 2–3 mendefinisikan section .data — area memori yang diisi di awal dan bisa dibaca/ditulis. msg db "Hello, World!", 0x0a mendeklarasikan array of bytes (db = define byte) berisi string pesan plus 0x0a (newline). Label msg menunjuk ke alamat awal array ini.

Baris 4 adalah trik yang wajib diingat: len equ $-msg menghitung panjang pesan secara otomatis. Simbol $ berarti "alamat di sini", jadi $-msg adalah selisih antara posisi saat ini dan alamat msg — jumlah byte persis dari string tersebut.

Section .text: Tempat Instruksi

Section .text berisi instruksi yang akan dieksekusi. global _start memberi tahu linker bahwa simbol _start adalah titik masuk program. Tanpa ini, ld tidak akan menemukan entry point.

Syscall write dan exit

Di Linux x86-64, cara berkomunikasi dengan kernel adalah instruksi syscall. Konvensinya: masukkan nomor syscall ke rax, argumen ke rdi, rsi, rdx (dst), lalu jalankan syscall.

  • write (nomor 1): rdi = file descriptor, rsi = buffer, rdx = panjang.
  • exit (nomor 60): rdi = exit code.

Inilah cara kerja paling fundamental: kalian tidak memanggil fungsi libc, kalian berbicara langsung ke kernel. Kita bedah tabel syscall Linux secara lengkap di episode 10.

Sekarang terjemahkan assembly menjadi biner:

Assemble dan link
cd ~/asm-lab/src
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
  • nasm -f elf64 menghasilkan object file ELF 64-bit (hello.o).
  • ld menghubungkannya menjadi executable hello tanpa libc sama sekali — ukurannya hanya sekitar 4 KB.

Tip

Wajib diingat: nasm hanya menerjemahkan syntax → machine code (assembling), ld yang menggabungkan object file dan menetapkan entry point (linking). Kedua langkah ini terpisah — di episode 19 kita akan menambahkan gcc sebagai linker untuk bisa memanggil libc.

Jalankan:

Jalankan program
./hello

Output yang benar:

Output
Hello, World!

Cek juga exit code dan ukuran biner:

Verifikasi exit code dan ukuran
echo $?               # 0
file hello           # ELF 64-bit LSB executable...
ls -l hello

Versi GAS (Sintaks AT&T)

Untuk perbandingan, program yang sama dalam GAS dengan sintaks AT&T (kita bedah lengkap di episode 4):

hello-att.s
.section .data
msg:    .ascii "Hello, World!\n"
len =   . - msg
 
.section .text
.global _start
 
_start:
    mov $1, %rax
    mov $1, %rdi
    lea msg(%rip), %rsi
    mov $len, %rdx
    syscall
 
    mov $60, %rax
    mov $0, %rdi
    syscall

Assemble dengan as lalu link:

Assemble GAS dan link
as hello-att.s -o hello-att.o
ld hello-att.o -o hello-att
./hello-att

Perhatikan perbedaan syntax yang mencolok: % sebelum register, $ sebelum immediate, dan urutan operan terbalik (mov $1, %rax vs mov rax, 1). Episode 4 akan membedah keduanya secara tuntas.

Common Pitfalls

Berikut kesalahan yang paling sering muncul pada Hello World pertama:

Warning

Lupa global _startld error entry point not found. Selalu deklarasikan global _start di section .text.

  • Lupa newline → output menempel dengan prompt berikutnya. Selalu akhiri string dengan 0x0a.
  • Salah nomor syscall → program mungkin hang atau mencetak sampah. Cek kembali rax: 1 untuk write, 60 untuk exit.
  • Salah lebar registereax (32-bit) vs rax (64-bit). Untuk syscall di kernel 64-bit, gunakan register 64-bit.
  • Lupa $ di GASmov 1, %rax akan ditafsirkan sebagai alamat memori, bukan nilai. Immediate harus diawali $.

Debugging dengan gdb (Pratinjau)

Bahkan Hello World bisa di-debug. Coba:

Inspeksi dengan gdb
gdb -q ./hello
(gdb) break _start
(gdb) run
(gdb) info registers rax
(gdb) stepi
(gdb) info registers rax
(gdb) quit

info registers rax akan menunjukkan bagaimana rax berubah setelah stepi — kalian melihat langsung satu instruksi mengubah mesin. Ini adalah kekuatan yang tidak dimiliki programmer Python. Detail gdb kita bedah di episode 16.

Important

Selalu verifikasi program assembly dengan echo $? setelah eksekusi. Exit code 0 berarti exit(0) dipanggil dengan benar. Jika program "hang" tanpa output, hampir pasti kalian lupa syscall exit — CPU terus mengeksekusi memori setelah program selesai hingga crash.

Penutup

Pada episode 3 ini, kalian telah menulis, meng-assemble, me-link, dan menjalankan program assembly pertama.

Inti yang harus dibawa pulang:

  • Siklus dasar: nasm -f elf64 hello.asm -o hello.o lalu ld hello.o -o hello.
  • Syscall di x86-64: nomor di rax, argumen di rdi/rsi/rdx, jalankan syscall.
  • section .data untuk data, section .text untuk kode, global _start untuk entry point.
  • db untuk byte, equ untuk konstanta, $ untuk alamat saat ini — kombinasi $-msg untuk menghitung panjang.
  • GAS memakai sintaks AT&T dengan % dan $; perbandingan lengkap menyusul.

Di episode 4 selanjutnya, kita bedah sintaks Intel vs AT&T secara menyeluruh: mengapa urutan operan berbeda, apa arti suffix b/w/l/q di GAS, dan bagaimana menerjemahkan dua dialek assembly ini dengan percaya diri — keterampilan yang menyelamatkan kalian saat membaca dokumentasi, disassembler, dan kode sumber kernel yang campur aduk.

Belajar Assembly - Instalasi & Hello World | Belajar Assembly