Low-level processor-specific symbolic language. We focus on user-mode x86 64-bit assembly, AT&T syntax.
Program composed of
.data is section with variables.text is section with code.byte/.word/.long/.quad defines integer (8/16/32/64 bits).ascii/.asciz defines string (without/with terminator)# is ignoredForm: mnemonic source, destination
mnemonic is short code telling CPU what to do (mov, add, push, pop, call, jmp, etc.)
b for byte, w for 16-bit word, l for 32-bit long, q for 64-bit quad)source and destination are operands
%rax, %rsp, %al)
displacement(base, index, scale)displacement+base+(index*scale)
base, index 64-bit registersdisplacement 32-bit constant or symbol (default 0)scale is 1, 2, 4, or 8 (default 1)%rax, %rbx, %rcx, %rdx, %rsi, %rdi, %r8-%r15`
%rax, low 32 bits is %eax, 16 bits is %ax, high 4 bits is %ah, low 4 bits is %al%rsp%rbp%rip%cs, %ds, etc.%crN, %drN, MSRs – only used in OS kernel)%stN, %mmN, %xmmN, %ymmN – only used with special instructions)0x401000, 8(%4bp), (%rdx, %rcx, 4))$42, $0x401000, only for source)Intel uses little endian ordering – from lowest address, you lay out bytes from the end (little address has end bytes)
Signed integers expressed in 2’s complement – sign change by flipping bits and adding one.
Comparisons:
cmp src1, src2 is like src2 - src1 but sets flags.test src1, src2 is like src1 & src2 but sets flagslea src, dst is dst = &src (src is in memory)Conditional jumps
jcc addr (or jncc for not)addr if cc holds, decided using flags register
e/z: result == 0b: dst < src (unsigned, a for above)l: dst < src (signed, g for above)s: result < 0 (signed)Data objects in data segment:
.data
myvar: .long 0x1234567, 0x23456789
bar: .word 0x1234
mystr: .asciz "foo"
Stack grows downwards (towards lower memory addresses).
Stack pointer (%rsp) points to top of stack
Stack composed of frames, which are pushed on stack during function calls.
Address of current frame stored in frame pointer register (on Intel, %rbp)
Each frame contains
Parameter passing in caller function for Linux
%rdi, then %rsi, %rdx, %rcx, %r8, %r9Prologue in called function
%rbp) on to stack%rbp to current stack pointer%rbx, %r12-%r15)sub $n, %rsp with n the size of local vars)enter opcode does everything except pushing callee-saved registersEpilogue in called function
%raxretleave restores stack pointer and rets