Syntax#

Assembly is a thin layer over machine code. Each line is one instruction (a mnemonic plus operands), one directive (a hint to the assembler), or a label (a named address). There are no expressions, no functions in the source sense; control flow is jumps and calls.

The two dialects the operator meets daily.

  • Intel syntax (Windows tooling, NASM, objdump -M intel, most disassemblers): destination on the left, mov rax, 1.

  • AT&T syntax (GCC default on Linux, objdump default): source on the left, register prefixes, suffix-typed mnemonics, movq $1, %rax.

/types`. For the operators and addressing modes, see Operators.

Intel syntax#

; nasm / intel syntax: dest, src
global  _start

section .text
_start:
    mov     rax, 60          ; syscall: exit
    mov     rdi, 0           ; status
    syscall

AT&T syntax#

# gas / AT&T syntax: src, dest; size-suffixed mnemonics
.globl _start

.text
_start:
    movq    $60, %rax        # syscall: exit
    movq    $0,  %rdi        # status
    syscall

The same instructions, different surface.

Intel

AT&T

mov rax, 1

movq $1, %rax

mov rax, [rbx]

movq (%rbx), %rax

mov rax, [rbx + rcx*8 + 16]

movq 16(%rbx,%rcx,8), %rax

add rax, rbx

addq %rbx, %rax

cmp rax, 10

cmpq $10, %rax

Register names: Intel writes rax; AT&T prefixes with % (%rax). Immediates: Intel writes 42; AT&T prefixes with $ ($42). Pick one and sticks to it within a file.

Comments#

NASM (Intel): ; runs to end-of-line. GAS (AT&T or Intel): # and //; block comments wrap with /* ... */.

; nasm comment
# gas comment
/* multi-line
   comment */

Directives#

Directives shape the output without emitting code. Common ones.

Directive

Effect

.text / section .text

executable code section

.data / section .data

initialised read-write data

.rodata / section .rodata

read-only data (strings, constants)

.bss / section .bss

zero-initialised data, allocated at load

.global, .globl / global

export a symbol so the linker can see it

.extern / extern

declare a symbol defined elsewhere

.byte, .word, .long, .quad

emit 1 / 2 / 4 / 8 bytes

.ascii, .asciz, .string

emit string bytes (.asciz adds the trailing null)

.align N

align the next thing to N bytes

%define, equ (NASM)

constant definition

.set, = (GAS)

constant definition

section .rodata
msg:    db  "hello, operator", 0xa
msg_len equ $ - msg

section .text
global _start
_start:
    mov     rax, 1            ; write
    mov     rdi, 1            ; stdout
    mov     rsi, msg
    mov     rdx, msg_len
    syscall

Labels#

A label is a name for the address of the next instruction or datum. Global labels are visible across files; local labels (.label in GAS, .label in NASM) are private to the nearest non-local label.

global add
add:
    lea     rax, [rdi + rsi]
    ret

.skip:                          ; local; reset by next global label
    inc     rax
    ret

Literals#

mov     rax, 42                 ; decimal
mov     rax, 0xff               ; hex (Intel)
mov     rax, 0o755              ; octal (NASM)
mov     rax, 0b1010_0001        ; binary (NASM)
mov     al, 'A'                 ; ASCII byte

db      0xde, 0xad, 0xbe, 0xef  ; byte sequence
dq      1, 2, 3                  ; quad words
movq    $42,    %rax            # decimal
movq    $0xff,  %rax            # hex
movb    $'A',   %al             # ASCII byte

.byte   0xde, 0xad, 0xbe, 0xef
.quad   1, 2, 3

References#