CPU Registers Explained
A register is a small, extremely fast storage location built directly into the CPU itself, holding a fixed number of bits — 64 on a modern x86-64 processor. Unlike RAM, which sits outside the CPU chip and requires dozens of clock cycles to access, a register can typically be read or written in a single clock cycle, making registers the fastest storage a program can use. Every arithmetic or logic operation an x86-64 CPU performs — addition, comparison, bitwise AND — operates on values sitting in registers, not directly on memory in most cases; data must first be loaded from RAM into a register before the CPU can compute on it. Because there are only a limited number of registers (16 general-purpose 64-bit registers on x86-64), assembly programmers and compilers must constantly decide which values are important enough to keep in a register versus which should be spilled back out to memory, a process called register allocation.
Cricket analogy: Registers are like the handful of balls a bowler like Jasprit Bumrah actually holds in his hand during an over, versus the full box of balls in the dressing room — only what's in-hand can be bowled immediately, the rest requires a trip back.
General-Purpose Registers
On x86-64, the general-purpose registers are named RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, and R8 through R15, each 64 bits wide, though many can also be accessed as smaller 32-bit (EAX), 16-bit (AX), or 8-bit (AL) sub-portions of the same physical register. While these are called 'general-purpose,' several carry conventional roles by tradition and by the calling convention a platform uses: RAX typically holds a function's return value, RCX, RDX, RSI, and RDI are commonly used to pass the first four integer arguments to a function under the System V AMD64 calling convention used on Linux and macOS, and RSP always points to the top of the current call stack. RBP is conventionally used as a frame pointer to reference local variables and function parameters relative to a fixed point within a stack frame, though optimizing compilers sometimes free it up as a thirteenth general-purpose register when frame-pointer omission is enabled.
Cricket analogy: General-purpose registers are like a T20 side's flexible batting order — Virat Kohli usually bats at 3, but the same slot can be reassigned depending on match situation, just as RAX conventionally holds a return value but can be repurposed.
Special-Purpose Registers: RIP and RFLAGS
Beyond the general-purpose set, x86-64 has registers with fixed, non-negotiable hardware roles. RIP, the instruction pointer, always holds the memory address of the next instruction the CPU will fetch and execute; a jmp or call instruction works by directly overwriting RIP, which is exactly how loops, function calls, and if/else branching are implemented at the hardware level. RFLAGS is a register where individual bits (flags) are automatically set or cleared as a side effect of arithmetic and comparison instructions — the Zero Flag (ZF) is set when a result equals zero, the Carry Flag (CF) is set on unsigned overflow, and the Sign Flag (SF) reflects the sign of a result. Conditional jump instructions such as je (jump if equal) or jl (jump if less) don't compare values themselves; they simply inspect the flags left behind by a preceding cmp instruction, which is why cmp is almost always immediately followed by a conditional jump in real assembly code.
Cricket analogy: RIP is like the umpire's mental note of which ball is coming next in the over — it always points to 'what happens next,' and a no-ball call (a jump) redirects the sequence exactly as jmp overwrites RIP.
; x86-64 NASM: registers, flags, and a conditional jump
section .text
global _start
_start:
mov rax, 10 ; RAX = 10
mov rbx, 10 ; RBX = 10
cmp rax, rbx ; compare RAX and RBX, sets ZF/SF/CF in RFLAGS
je equal_case ; jump if Zero Flag is set (RAX == RBX)
mov rdi, 1 ; not taken in this example
jmp done
equal_case:
mov rdi, 0 ; exit code 0 means "they were equal"
done:
mov rax, 60 ; syscall number for exit
syscallNever assume a register's value survives a function call unless the calling convention guarantees it. Under System V AMD64, RAX, RCX, RDX, RSI, RDI, R8-R11 are 'caller-saved' and may be overwritten by any called function; only RBX, RBP, RSP, R12-R15 are 'callee-saved.' Forgetting this is a classic source of subtle bugs in hand-written assembly.
- Registers are the CPU's fastest storage, built directly into the chip and accessed in a single clock cycle, unlike RAM.
- x86-64 has 16 general-purpose 64-bit registers (RAX-RDX, RSI, RDI, RBP, RSP, R8-R15), each also addressable as smaller 32/16/8-bit sub-registers.
- Register roles like 'RAX returns a value' or 'RDI holds the first argument' are calling-convention conventions, not hardware restrictions.
- RIP (instruction pointer) always holds the address of the next instruction; jmp and call directly overwrite it.
- RFLAGS holds bits like ZF, CF, and SF that are set automatically by arithmetic/comparison instructions such as cmp.
- Conditional jumps (je, jl, jg) read RFLAGS rather than recomputing a comparison themselves.
- The System V AMD64 calling convention divides registers into caller-saved and callee-saved sets, which every assembly function must respect.
Practice what you learned
1. Why are CPU registers faster to access than RAM?
2. What does the RIP register always hold on x86-64?
3. What triggers the Zero Flag (ZF) in RFLAGS to be set?
4. Under the System V AMD64 calling convention, what is true of a caller-saved register like RAX?
Was this page helpful?
You May Also Like
What Is Assembly Language?
An introduction to assembly language as the human-readable face of machine code, and why understanding it still matters for serious programmers.
Memory Addressing Modes
How assembly instructions specify where an operand's value actually lives — immediate, register, direct, and indexed addressing explained with examples.
Your First Assembly Program
A hands-on walkthrough of writing, assembling, linking, and running a minimal x86-64 Linux assembly program from scratch.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics