Belajar Assembly - Sintaks: Intel vs AT&T
Episode 4 of 23

Belajar Assembly - Sintaks: Intel vs AT&T

Dua dialek utama assembly x86: sintaks Intel yang dipakai NASM (mov dest, src, dengan size byte/word/dword/qword) dan sintaks AT&T yang dipakai GAS (mov src, dest, dengan suffix b/w/l/q dan prefix % untuk register, $ untuk immediate), beserta cara menerjemahkan antara keduanya dengan percaya diri.

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

Pendahuluan

Setelah di episode 3 kalian menjalankan Hello World, kalian pasti sadar ada dua cara menulis instruksi yang sama: NASM (mov rax, 1) dan GAS (mov $1, %rax). Keduanya menghasilkan machine code yang identik, tetapi sintaksnya terlihat seperti dua bahasa berbeda. Episode 4 membedah keduanya sampai tuntas.

Mengapa ini penting? Karena di dunia nyata kalian akan bertemu keduanya terus-menerus: dokumentasi Intel memakai sintaks Intel, kernel Linux dan toolchain GNU memakai AT&T, sedangkan objdump bisa diatur ke keduanya, dan Ghidra/radare2 sering memakai Intel. Kemampuan membaca dua dialek ini akan menyelamatkan kalian berkali-kali — termasuk saat debugging di episode 16.

Dua Dialek, Satu Mesin

Sintaks hanyalah cara menulis instruksi; opcode yang dihasilkan tetap sama. Perbedaan mendasar ada tiga:

AspekIntel (NASM)AT&T (GAS)
Urutan operanmov dest, srcmov src, dest
Prefix registerTidak ada%%rax
Prefix immediateTidak ada$$1
Ukuran operanKeyword (byte/word/dword/qword)Suffix (b/w/l/q)
Alamat memori[rax + rcx*4 + 16]16(%rax,%rcx,4)
Komentar;# atau /* */

Urutan Operan: Sumber Dulu atau Tujuan Dulu?

Ini sumber kebingungan nomor satu. Di sintaks Intel, destinasi di kiri: mov rax, rbx berarti "salin rbx ke rax". Di AT&T, sumber di kiri: mov %rbx, %rax berarti hal yang sama. Ingatlah AT&T sebagai "tempatkan A ke B": mov %a, %bb = a.

Sufiks huruf besar vs kecil tidak masalah; yang penting konsistensi. Untuk semua episode series ini, kode utama memakai NASM (Intel).

Prefix Register dan Immediate

Di AT&T, setiap register diawali % (%rax, %rsp) agar tidak tertukar dengan label, dan setiap immediate diawali $ ($42, $-1). Aturan praktis: di GAS, jika tidak ada $, nilai dianggap alamat memori.

Menentukan Ukuran Operan

Intel: Keyword Eksplisit

Di NASM, ukuran ditentukan oleh nama register atau keyword eksplisit:

Ukuran operan di Intel
mov al, 0x41          ; 8 bit  (byte)   → AL
mov ax, 0x4142        ; 16 bit (word)   → AX
mov eax, 0x41424344   ; 32 bit (dword)  → EAX
mov rax, 0x4142434445464748 ; 64 bit (qword) → RAX
 
; Untuk operan memori yang ambigu, wajib ada keyword:
mov byte [rbx], 0x41
mov word [rbx], 0x4142
mov dword [rbx], 0x41424344
mov qword [rbx], 0x4142434445464748

AT&T: Suffix di Instruksi

Di GAS, ukuran disandikan sebagai suffix pada mnemonic: b (byte/8), w (word/16), l (long/32), q (quad/64):

Suffix ukuran di AT&T
movb $0x41, %al
movw $0x4142, %ax
movl $0x41424344, %eax
movq $0x4142434445464748, %rax
 
movb $0x41, (%rbx)
movw $0x4142, (%rbx)
movl $0x41424344, (%rbx)
movq $0x4142434445464748, (%rbx)

Perhatikan: movl berarti operasi 32-bit, bukan "long mode" 64-bit. Suffix ini adalah salah satu tempat tersering programmer NASM tersesat saat baca kode GAS.

Addressing Mode di Dua Dialek

Ingat sintaks Intel [rbx + rcx*4 + 16] dari episode 5 (nanti)? Di AT&T, formatnya dibalik dan dipisah koma: 16(%rbx,%rcx,4). Polanya displacement(base,index,scale).

IntelAT&TArti
[rax](%rax)Alamat di rax
[rax + 16]16(%rax)rax + 16
[rbx + rcx*4](%rbx,%rcx,4)rbx + rcx*4
[rbx + rcx*4 + 16]16(%rbx,%rcx,4)rbx + rcx*4 + 16

Jika kalian membaca disassembly objdump, ketahui bahwa objdump -d default memakai AT&T, sedangkan objdump -d -M intel menampilkan Intel:

Disassemble dengan dua dialek
objdump -d hello          # AT&T (default)
objdump -d -M intel hello # Intel

Contoh Terjemahan Langsung

Mari terjemahkan program kecil dari episode 3 antara kedua dialek:

NASM (Intel)
section .data
msg db "Halo", 0x0a
len equ $-msg
section .text
global _start
_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, len
    syscall
    mov rax, 60
    mov rdi, 0
    syscall
GAS (AT&T)
.section .data
msg: .ascii "Halo\n"
len = . - msg
.section .text
.global _start
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $msg, %rsi
    mov $len, %rdx
    syscall
    mov $60, %rax
    mov $0, %rdi
    syscall

Tip

Perbedaan lain yang sering menjebak: di GAS, mov $msg, %rsi memuat alamat label msg sebagai immediate. Di NASM, mov rsi, msg juga memuat alamat label (NASM memperlakukan label sebagai alamat). Konsisten di kedua dialek, tapi ingat: tanpa $ di GAS, mov msg, %rsi justru memuat isi memori — 8 byte pertama dari label tersebut.

Cara Membaca Disassembly Campuran

Di dunia nyata, kalian akan membaca file yang memakai kedua dialek. Berikut translasi cepat untuk instruksi yang paling umum:

Instruksi (Intel)Instruksi (AT&T)Makna
mov eax, ebxmovl %ebx, %eaxeax = ebx
add rax, 16addq $16, %raxrax += 16
cmp eax, 5cmpl $5, %eaxbandingkan eax dengan 5
lea rax, [rsi+rdi]leaq (%rsi,%rdi), %raxrax = rsi + rdi
call funccall funcpanggil func
push rbppushq %rbpdorong rbp ke stack

Ingat juga: di AT&T, cmp dan test membalik arah perbandingan. cmp $5, %eax di AT&T setara cmp eax, 5 di Intel — nilai dibandingkan dalam urutan terbalik, dan flag yang dihasilkan ikut terbalik, yang memengaruhi pilihan jump (jl vs jg). Ini pitfall klasik yang membingungkan banyak programmer.

Warning

Hati-hati saat menerjemahkan cmp/test antara dua dialek: karena urutan operan terbalik, kondisi jump yang "jelas" di satu dialek bisa jadi terbalik di dialek lain. Jika ragu, selalu uji dengan input nyata — atau seragamkan ke satu dialek (disarankan NASM/Intel) untuk kode produksi.

Penutup

Pada episode 4 ini, kalian telah menguasai dua dialek assembly x86.

Inti yang harus dibawa pulang:

  • Intel (NASM): mov dest, src, ukuran via keyword byte/word/dword/qword.
  • AT&T (GAS): mov src, dest, prefix %/$, ukuran via suffix b/w/l/q.
  • Addressing: [rbx+rcx*4+16] vs 16(%rbx,%rcx,4).
  • objdump -d default AT&T; gunakan -M intel untuk Intel.
  • Perhatikan urutan terbalik pada cmp/test saat menerjemahkan jump.

Di episode 5 selanjutnya, kita bedah fondasi yang paling sering dipakai: register, tipe data, dan addressing modes x86-64 — peta lengkap register general-purpose raxr15, sub-register eax/ax/al/ah, flags rflags, serta lima cara CPU mengakses data: immediate, register, direct memory, indirect, dan indexed. Pastikan kalian hafal kedua dialek di episode ini, karena semua kode berikutnya akan memakainya terus.