x86-64 assembly: 50 cards on registers, instructions and calling conventions
x86-64 assembly in Intel syntax: registers and sub-registers, flags, mov and lea, jumps, the stack frame, the System V calling convention and Linux syscalls.
Practice now
Study without an account
Scheduled with the default Askesis timings. Progress is saved in this browser.
All 50 cards
- 1The 16 general-purpose registers of x86-64
rax,rbx,rcx,rdx,rsi,rdi,rbp,rspandr8tor15 - 2The smaller registers inside
raxeax(low 32 bits),ax(low 16 bits),al(low 8 bits) andah(bits 8 to 15) - 3The smaller registers inside
r8r8d(low 32 bits),r8w(low 16 bits) andr8b(low 8 bits) - 4The 8-bit registers of
rsi,rdi,rbpandrspsil,dil,bplandsplThey need a REX prefix, so an instruction that uses one of them can’t also useah,bh,chordh. - 5What happens to the upper half of
raxaftermov eax, 1?It is zeroed: writing a 32-bit register zero-extends the result into the full 64-bit registerWritingaxoralleaves the other bits unchanged. - 6What do
ripandrflagshold?ripholds the address of the next instruction to run;rflagsholds the status flags (ZF, SF, CF, OF and others) and control bits such as the direction flag - 7Why do compilers zero a register with
xor eax, eax?It clears all ofraxin 2 bytes instead of the 5 ofmov eax, 0, and CPUs recognize it as a zeroing idiomUnlikemov, it also changes the flags. - 8Sizes of a byte, word, dword and qword1, 2, 4 and 8 bytesA word is 16 bits for historical reasons: it was the 8086’s register size.
- 9The four main status flagsZF: the result was zero. SF: the result’s sign bit is set. CF: an unsigned carry or borrow. OF: a signed overflow
- 10What does
cmp rax, rbxdo?Computesrax - rbx, sets the flags assubwould, and throws the result away - 11What does
test rax, raxdo?ANDsraxwith itself to set the flags without storing anything: ZF is set whenraxis zero, and SF when it is negativeUsually followed byjzorjnz.test al, 1checks the lowest bit. - 12Signed vs unsigned conditional jumpsSigned comparisons use
jl,jle,jg,jge(less, greater); unsigned ones usejb,jbe,ja,jae(below, above)Signed jumps read SF, OF and ZF; unsigned jumps read CF and ZF. - 13
jevsjzTwo names for the same instruction: jump if ZF is setLikewisejneandjnzboth jump if ZF is clear. - 14Jump to
.smallifrdiis less than 10, as a signed numberx86asmcmp rdi, 10 jl .smallFor unsigned values, usejbinstead. - 15A loop that runs its body 10 timesx86asm
mov ecx, 10 .next: ; loop body dec ecx jnz .nextdecsets ZF when the counter reaches zero, so nocmpis needed. - 16Set
raxto the larger ofrdiandrsi(signed) without a branchx86asmmov rax, rdi cmp rdi, rsi cmovl rax, rsi ; if rdi < rsi, rax = rsi - 17Turn a comparison into 0 or 1x86asm
cmp rdi, rsi sete al movzx eax, al ; rax = 1 if rdi == rsi, else 0setccwrites only one byte, so zero-extend it before using the full register. - 18
mov rax, [rbx+8]vslea rax, [rbx+8]movloads the 8 bytes stored at addressrbx+8;leaputs the addressrbx+8itself inraxwithout touching memory - 19Multiply
rdiby 5 with a singleleax86asmlea rax, [rdi+rdi*4]leacan do this kind of arithmetic in one instruction, and it doesn’t change the flags. - 20The general form of a memory operand
[base + index*scale + displacement], where scale is 1, 2, 4 or 8 and the displacement is a signed 32-bit constantrspcan be a base but never an index. - 21Can
movcopy directly from memory to memory?No. At most one operand can be in memory, so load the value into a register firstString instructions such asmovsbare the exception. - 22Why does
mov [rax], 1fail to assemble?Nothing says how many bytes to write; add a size:mov qword [rax], 1GNU as in Intel mode and MASM write itqword ptr [rax]. - 23
movzxvsmovsxBoth load a smaller value into a larger register:movzxfills the upper bits with zeros,movsxwith copies of the sign bitx86asmmovzx eax, byte [rdi] ; unsigned char movsx rax, word [rdi] ; signed short movsxd rax, dword [rdi] ; signed int - 24Load the address of
msgwith RIP-relative addressingx86asmlea rax, [rel msg]GNU as writeslea rax, [rip + msg]. Addresses relative toripkeep code position-independent. - 25How big can an immediate operand be?Usually 32 bits, sign-extended to 64; only
movinto a 64-bit register accepts a full 64-bit immediateGNU as calls that formmovabs. - 26Which byte does
mov dword [rdi], 0x12345678store at the lowest address?0x78: x86 is little-endian, so the bytes in memory are78 56 34 12 - 27
inc raxvsadd rax, 1Both add one, butincleaves CF unchanged whileaddupdates it - 28Unsigned 64-bit division with
div rcxDivides the 128-bit value inrdx:raxbyrcx: the quotient goes toraxand the remainder tordx. ZerordxfirstFor signedidiv, sign-extendraxintordxwithcqo. Dividing by zero raises an exception (SIGFPE on Linux). - 29
shrvssarshrshifts in zeros, dividing an unsigned value by a power of two;sarcopies the sign bit, dividing a signed valuesarrounds toward negative infinity: shifting -7 right by one gives -4, whileidivby 2 gives -3. - 30What do
push raxandpop raxdo?pushsubtracts 8 fromrsp, then storesraxat[rsp];poploads[rsp]intorax, then adds 8 torspThe stack grows toward lower addresses. - 31What does
call funcdo?Pushes the return address (the address of the next instruction) and jumps tofunc - 32What does
retdo?Pops the return address off the stack and jumps to it - 33A function prologue and epilogue with a frame pointerx86asm
func: push rbp mov rbp, rsp sub rsp, 16 ; room for locals ; ... leave ; mov rsp, rbp, then pop rbp ret - 34After
push rbpandmov rbp, rsp, what are[rbp],[rbp+8]and[rbp-8]?The caller’s savedrbp, the return address, and the first 8-byte slot for local variablesWith System V, arguments passed on the stack start at[rbp+16]. - 35Which registers carry the first six integer or pointer arguments (System V AMD64)?
rdi,rsi,rdx,rcx,r8,r9, in that order; any further arguments go on the stackWindows x64 differs: it usesrcx,rdx,r8,r9and reserves 32 bytes of shadow space. - 36Where does a function return an integer or pointer (System V AMD64)?In
rax; a 128-bit value usesrdx:rax - 37Floating-point arguments and return values (System V AMD64)Arguments go in
xmm0toxmm7; adoubleorfloatcomes back inxmm0 - 38Callee-saved registers in System V AMD64
rbx,rbpandr12tor15(andrsp): a function that uses them must restore them before returning - 39Caller-saved registers in System V AMD64
rax,rcx,rdx,rsi,rdi,r8tor11and allxmmregisters: any call may change them, so save them yourself if you need them afterwards - 40Stack alignment rule for a
call(System V AMD64)rspmust be a multiple of 16 just before thecall, so on entry to a functionrspis 8 bytes past a 16-byte boundaryThat’s whyrspis 16-byte aligned again once a function has pushedrbp. - 41What is the red zone?The 128 bytes below
rspthat a function may use without movingrsp; signal handlers won’t overwrite themHandy for leaf functions. Kernel code is compiled without it. - 42What goes in
albefore calling a variadic function such asprintf?An upper bound on the number of vector registers used to pass arguments, soxor eax, eaxwhen there are no floating-point arguments - 43Implement
int sum(int a, int b)x86asmsum: lea eax, [rdi+rsi] retaarrives inedi,binesi, and the result is returned ineax. - 44How do you make a Linux system call in x86-64?Put the syscall number in
raxand arguments inrdi,rsi,rdx,r10,r8,r9, then runsyscall; the result comes back inrax, with a negative errno on failure - 45Why does the fourth syscall argument go in
r10rather thanrcx?syscalloverwritesrcxwith the return address (andr11withrflags) - 46Print
hiand exit with status 0 on Linuxx86asmsection .data msg: db "hi", 10 len equ $ - msg section .text global _start _start: mov eax, 1 ; write mov edi, 1 ; stdout lea rsi, [rel msg] mov edx, len syscall mov eax, 60 ; exit xor edi, edi ; status 0 syscall - 47What goes in the
.text,.data,.rodataand.bsssections?Code; initialized writable data; read-only data such as string constants; zero-initialized data, which takes no space in the file - 48Assemble and link a NASM program on Linuxbash
nasm -f elf64 hello.asm -o hello.o ld hello.o -o helloTo call C library functions, definemaininstead of_startand link withgcc. - 49How does AT&T syntax differ from Intel syntax?AT&T puts the source first and the destination last, prefixes registers with
%and immediates with$, and adds size suffixes: AT&Tmovq $1, %raxis Intelmov rax, 1GNU as and objdump use AT&T by default;objdump -d -M intelshows Intel syntax. - 50What is the AT&T operand
8(%rbp,%rcx,4)in Intel syntax?[rbp+rcx*4+8]: AT&T writes displacement(base, index, scale)
Frequently asked questions
Intel or AT&T syntax?
Intel syntax, as NASM writes it. GNU as and objdump default to AT&T syntax, so two cards show how to translate it.
Does it cover Windows?
The calling convention cards follow System V AMD64, used by Linux, macOS and the BSDs, and the system call cards are Linux-only. One card notes how the Windows x64 convention differs.
Do I need to know C?
It helps. Several cards relate assembly to C functions and types, but the registers and instructions stand on their own.
More in Programming
JavaScript
Master the JavaScript every developer uses daily: scope, closures, equality, array methods, promises, async/await and the event loop.
50 cardsAdvanced JS
Fifty advanced JavaScript cards: event-loop ordering puzzles, generators and async iteration, this binding, Proxy and Reflect, modules, AbortController and coercion edge cases.
50 cardsTypeScript
Learn the TypeScript you use every day: narrowing, generics, keyof, mapped and conditional types, utility types, satisfies and strict mode, with code on every card.
50 cardsPython
Learn idiomatic Python fast: comprehensions, f-strings, args and kwargs, generators, decorators, context managers and the standard library.
50 cardsGit & terminal
The Git commands and shell skills developers use every day: branching, rebasing, undoing mistakes, pipes, redirects, permissions and processes.
50 cardsJava
Core Java with short snippets: equals vs ==, records, sealed types, collections, generics, exceptions, streams, lambdas and JVM basics.
50 cardsC#
C# and .NET fundamentals with short snippets: value vs reference types, properties, records, nullable reference types, LINQ, async/await and DI.
50 cardsKotlin
Kotlin fundamentals with short snippets: null safety, val vs var, data and sealed classes, extension functions, scope functions and coroutines.
50 cardsSwift
Swift fundamentals with short snippets: optionals, structs vs classes, protocols, enums with associated values, closures, ARC, async/await and SwiftUI.
50 cardsFlutter
Flutter and Dart basics: null safety, futures and streams, stateless vs stateful widgets, setState, hot reload, keys, layout and state management.
50 cardsPHP
Modern PHP 8 with short snippets: strict types, arrays, match, nullsafe and named arguments, enums, readonly, Composer, PDO and password_hash.
50 cardsRuby
Ruby fundamentals with short snippets: blocks, procs and lambdas, symbols, Enumerable, mixins, truthiness, method_missing, gems and Bundler.
50 cardsGo
Go (Golang) fundamentals with short, idiomatic snippets: slices vs arrays, maps, defer, error wrapping, interfaces, goroutines, channels, select and context.
50 cardsRust
Learn the Rust that the compiler keeps asking about: ownership, borrowing, lifetimes, Option and Result, traits, closures, smart pointers and async.
50 cardsC++
Modern C++ in short snippets: references vs pointers, RAII, smart pointers, move semantics, STL containers and algorithms, const, templates and UB.
50 cardsHaskell
Haskell fundamentals with short code: types and type classes, pattern matching, laziness, Maybe and Either, folds, Functor, Applicative and Monad.
50 cardsElixir
Elixir fundamentals with short snippets: immutability, pattern matching, the pipe operator, Enum vs Stream, processes, GenServer, supervisors and mix.
50 cardsRegex
Learn regular expressions for good: anchors, classes, greedy vs lazy quantifiers, groups, lookarounds, flags, replacements and the backtracking trap.
50 cards