Assembly Language - Registers
A register is a high-speed storage unit inside the CPU, and is the most frequently manipulated object in assembly programming. Understanding registers is the key first step to learning assembly language well.
What is a Register
Registers are integrated inside the CPU chipUltra-high-speed small memory storage, used to temporarily store instructions, data, and addresses.
Unlike memory, registers are embedded inside the CPU. The CPU can access registers with almost zero latency, whereas accessing memory requires dozens to hundreds of clock cycles.
In assembly language, the vast majority of operations revolve around registers—data is loaded from memory into registers, operations are performed in registers, and then the results are stored back to memory.
You can think of registers as the CPU's "workbench." Tools on the workbench are available at any time, while memory is like a warehouse that you need to walk over to fetch and store items.
x86 32-bit Register Classification
The x86 32-bit architecture provides many types of registers, each with different purposes. The following figure shows the complete register classification:
Below we introduce each type of register in detail:
General Purpose Registers
General Purpose RegistersThey are the most commonly used registers, used to store operation data and temporary results.
x86 provides 8 32-bit general-purpose registers:
| 32-bit | 16-bit | Low 8 bits | High 8 bits (of low 16 bits) | Main purpose |
|---|---|---|---|---|
| EAX | AX | AL | AH | Accumulator, stores function return values and arithmetic operation results |
| EBX | BX | BL | BH | Base register, often used to store memory base addresses |
| ECX | CX | CL | CH | Counter, often used for loop counting and shifts |
| EDX | DX | DL | DH | Data register, stores the high-order results of multiplication and division |
| ESI | SI | SIL | - | Source index register, source address for string operations |
| EDI | DI | DIL | - | Destination index register, destination address for string operations |
| EBP | BP | BPL | - | Base pointer, points to the bottom of the current stack frame |
| ESP | SP | SPL | - | Stack pointer, always points to the top of the stack |
Naming convention: The E prefix means Extended (extended to 32 bits), and the X suffix indicates that it can be split into high and low bytes.
Example
; Demonstrate access to different parts of registers
section .text
global _start
_start:
mov eax, 0x12345678 ; Complete 32-bit register
; At this point: EAX = 0x12345678
; AX = 0x5678 (low 16 bits)
; AH = 0x56 (high 8 bits, i.e., the high 8 bits of AX)
; AL = 0x78 (low 8 bits)
mov ax, 0xAABB ; Modify AX (low 16 bits)
; At this point: EAX = 0x1234AABB (the high 16 bits remain unchanged!)
; AX = 0xAABB
; AL = 0xBB
mov al, 0xCC ; Modify AL (lowest 8 bits)
; At this point: EAX = 0x1234AACC (only the low 8 bits changed)
; AX = 0xAACC
; AL = 0xCC
mov eax, 1
mov ebx, 0
int 0x80
When modifying the low 16 bits of a 32-bit register (such as AX), the high 16 bits remain unchanged. However, when a 32-bit register is used as the destination operand, the entire 32 bits are overwritten. This is a common source of errors for beginners.
Segment Registers
Segment registers are used to specify the currently used memory segment:
| Register | Name | Purpose |
|---|---|---|
| CS | Code segment register | Points to the segment where the current instruction is located |
| DS | Data segment register | Points to the segment where data is located |
| SS | Stack segment register | Points to the segment where the stack is located |
| ES | Extra segment register | Additional data segment |
| FS | Extra segment register | General purpose, often used for thread-local storage |
| GS | Extra segment register | General-purpose, commonly used for thread-local storage |
When programming in 32-bit protected mode, the operating system has already set up the segment registers, so you usually don't need to modify them manually.
Pointer and Index Registers
These registers are mainly used to access memory and store memory addresses:
| Register | Full name | Purpose |
|---|---|---|
| EIP | Instruction Pointer | Points to the address of the next instruction to be executed by the CPU (not directly accessible) |
| ESP | Stack Pointer | Points to the top of the stack; PUSH/POP instructions automatically adjust it |
| EBP | Base Pointer | Points to the bottom of the current function's stack frame, used to access function parameters and local variables |
| ESI | Source Index | Source address for string/memory operations |
| EDI | Destination Index | Destination address for string/memory operations |
ESP and EBP cannot be used freely as ordinary general-purpose registers. ESP points to the top of the stack, and push/pop/call/ret all change it; EBP is key to accessing function parameters. Modifying them arbitrarily will cause the program to crash.
Flag Register (EFLAGS)
EFLAGSIt is a 32-bit register, each bit represents a status flag.
You cannot directly read or write the entire EFLAGS, but the CPU automatically updates these flag bits based on operation results, and conditional jump instructions use them to decide whether to jump.
| Flag bit | Name | Meaning |
|---|---|---|
| CF | Carry Flag | Set to 1 when unsigned arithmetic produces a carry/borrow |
| PF | Parity Flag | Set to 1 when the number of 1s in the low 8 bits of the result is even |
| AF | Auxiliary Carry Flag | Set to 1 when there is a carry/borrow from the low 4 bits to the high 4 bits |
| ZF | Zero Flag | Set to 1 when the operation result is 0 |
| SF | Sign Flag | Set to 1 when the operation result is negative (equal to the most significant bit of the result) |
| OF | Overflow Flag | Set to 1 when signed arithmetic overflows |
Example
; Demonstrates the effect of arithmetic on flag bits
section .text
global _start
_start:
mov eax, 10
sub eax, 10 ; 10 - 10 = 0
; ZF = 1 (result is zero)
; SF = 0 (result is non-negative)
; CF = 0 (no borrow)
mov eax, 0xFFFFFFFF
add eax, 1 ; 0xFFFFFFFF + 1 = 0x100000000 (exceeds 32 bits)
; ZF = 1 (32-bit result is 0)
; CF = 1 (carry produced)
; OF = 0 (no overflow from a signed perspective)
mov eax, 1
mov ebx, 0
int 0x80
Register Usage Conventions
In actual programming, some registers have conventional uses—calledCalling Convention:
| Register | Purpose in the calling convention |
|---|---|
| EAX | Store function return value |
| ECX | Counter (loop count) |
| EDX | Store the high part of division results, extend EAX |
| EBX、ESI、EDI、EBP | Callee-saved: the called function must save and restore |
| EAX、ECX、EDX | Caller-saved: the caller is responsible for saving |
Other extensionsWhen writing your own assembly programs, you don't have to strictly follow the calling convention. But if you're mixing with C, you must follow the cdecl calling convention.