x86 Architectural Registers

Last update: 2024-07-28 09:42:04 +0800 +0800
tags: X86 | X86-64 | Assembly
Available translations: 日本語 / 中文(简体) / 中文(繁體)

x86 architectural registers hold programmer-visible integer, control, status, address-translation, debug, floating-point, and vector state. Width and availability depend on execution mode and enabled extensions. Calling conventions assign software roles to a subset of these registers but do not change their architectural behavior.

General-Purpose Registers and Subregisters #

IA-32 exposes EAX, EBX, ECX, EDX, ESI, EDI, EBP, and ESP. x86-64 widens them to RAX through RSP and adds R8 through R15. Subregisters name parts of the same architectural register:

  • RAX is 64 bits, EAX is its low 32 bits, AX is the low 16 bits, and AL and AH name low and high bytes of AX.
  • Writing a 32-bit destination in 64-bit mode clears the upper 32 bits.
  • Writing a 16-bit or 8-bit destination preserves the other bits.
  • A REX prefix makes SPL, BPL, SIL, and DIL available but prevents an instruction from encoding AH, BH, CH, or DH.

RIP is the 64-bit instruction pointer, while EIP is used by 32-bit code. Ordinary MOV cannot write it; branches, calls, returns, exceptions, and interrupt returns change control flow. RSP is the current stack pointer.

Register purpose at a function boundary comes from an ABI. System V AMD64 uses RDI, RSI, RDX, RCX, R8, and R9 for initial integer arguments, whereas Microsoft x64 uses RCX, RDX, R8, and R9. RBP can serve as a frame pointer but may be available as a general register when the ABI and unwind information permit. A Linux syscall uses another register convention, so function-call and kernel-entry roles must not be conflated.

RFLAGS #

RFLAGS extends the older EFLAGS and FLAGS registers. Common arithmetic status bits are:

FlagMeaning
CFUnsigned carry or borrow
PFEven parity of the low result byte
AFAuxiliary carry for legacy decimal operations
ZFZero result
SFSign bit of the result
OFSigned overflow

Control and system bits include:

  • DF, which chooses incrementing or decrementing indexes for string instructions.
  • IF, which controls delivery of maskable interrupts subject to privilege and virtualization rules.
  • TF, which requests a debug trap after an instruction.
  • IOPL, which participates in port-I/O and selected interrupt-control checks.
  • NT, which records nested hardware-task state in legacy protected mode.
  • RF, VM, AC, VIF, VIP, and ID, whose meanings depend on mode and enabled facilities.

Instructions define which flags they write, preserve, or leave undefined. PUSHF/POPF, interrupt entry, and return operations also apply privilege restrictions; software cannot assume every visible bit can be changed at its current CPL.

Segment Registers and Hidden Descriptor Caches #

CS, SS, DS, ES, FS, and GS have a visible selector and hidden descriptor state. Loading a selector in protected mode fetches a descriptor and caches its base, limit, type, and access rights. Editing the descriptor table does not update an already loaded cache.

In 64-bit mode, normal address generation ignores the bases and limits of CS, SS, DS, and ES. FS and GS retain 64-bit bases set through model-specific registers or supported instructions, which operating systems use for thread-local and per-CPU data. Selector and descriptor rules still apply where the architecture specifies them.

GDTR and IDTR hold a linear base and byte limit for the global descriptor table and interrupt descriptor table. LDTR and TR hold selectors plus cached descriptors for the local descriptor table and task-state segment. LGDT, LIDT, LLDT, and LTR establish those values under privilege checks. x86 Protected Mode and Privilege describes the table formats and transitions.

Control and System Registers #

Control registers configure execution and address translation:

  • CR0 includes protected-mode, paging, write-protect, caching, and selected numeric-state controls.
  • CR2 receives the linear address associated with a page fault.
  • CR3 selects the paging-structure root and can carry a process-context identifier when PCID is enabled.
  • CR4 enables architectural facilities such as PAE, global pages, OS-managed SIMD state, SMEP, SMAP, and protection keys when supported.
  • CR8 controls the task-priority threshold for external interrupts in 64-bit mode.

Model-specific registers (MSRs) provide additional controls, including EFER for long-mode and no-execute enablement, system-call targets, FS/GS bases, memory types, and performance monitoring. The exact MSR set is model-dependent and must be discovered or selected from vendor documentation. RDMSR and WRMSR are privileged.

Debug Registers #

DR0 through DR3 hold linear breakpoint addresses. DR7 enables breakpoints and selects execution, write, or data-access conditions with supported lengths. DR6 reports why a debug exception occurred. Reserved encodings and general- detect behavior are architecture-specific, so a debugger or kernel must sanitize values before restoring untrusted debug state.

Software breakpoints instead replace an instruction byte with INT3. Hardware debug registers avoid changing code but provide only a small number of slots. Debug exceptions interact with single stepping, task switching, virtualization, and transactional execution.

x87, MMX, SIMD, and Mask Registers #

The x87 floating-point unit exposes an eight-entry register stack plus control, status, tag, instruction-pointer, and data-pointer state. MMX aliases the low 64-bit storage of the x87 registers, which is why legacy MMX code executes EMMS before returning to x87 operations.

SSE introduced XMM registers. AVX extends their low storage into YMM; AVX-512 extends it into ZMM and adds opmask registers K0 through K7. Architecture and mode determine how many registers are visible. Writing a legacy SSE destination can preserve upper vector state, while VEX- and EVEX-encoded operations apply their specified upper-bit clearing behavior. Mixing forms can therefore create dependencies or transition penalties on selected processors.

MXCSR controls SIMD floating-point rounding, exception masks, status, and denormal handling. Opmask registers govern per-lane AVX-512 merging or zeroing. Additional extensions can add tile or other state that is not represented by the original floating-point save formats.

Extended-State Management #

FXSAVE and FXRSTOR cover x87, MMX, SSE, and related control state. The XSAVE family uses XCR0, CPUID enumeration, and a component bitmap to manage an extensible state area. Supervisor components can use additional control and save mechanisms.

An operating system must enable only state components it can initialize, save, restore, and expose safely. User software checks both processor support and OS enablement before executing AVX or later instructions. Context-switch policy can save state eagerly or with supported optimizations, but the architectural state visible to each thread must remain isolated.

Comments

Read or comment on GitHub (sign-in required to comment)