Lesson 08-Registers and Memory

CPU Register Architecture

Core Components of the CPU

  • Arithmetic Logic Unit (ALU): Executes arithmetic operations (addition, subtraction, multiplication, division) and logical operations (AND, OR, NOT).
  • Control Unit (CU): Coordinates the operation of various components, fetches instructions from memory, and executes them.
  • Register File: High-speed storage units inside the CPU (nanosecond-level access speed) used to temporarily hold data and addresses.

General-Purpose Registers and Their Evolution

32-bit General-Purpose Registers:

RegisterPrimary UseSpecial Function
EAXArithmetic / Return ValueImplicit operand in multiply/divide instructions
EBXBase PointerMay be reserved by the operating system
ECXLoop CounterImplicit counter in string operations
EDXI/O Operations / Extended PrecisionStores high-order bits in multiply/divide

64-bit Extensions:
RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8–R15

  • Added registers R8–R15 (require REX prefix)

Register Operation Examples:

mov eax, 0x12345678        ; 32-bit assignment
mov rax, 0x1122334455667788 ; 64-bit assignment
mov ebx, eax               ; Transfer between 32-bit registers

Key x86 Registers (32-bit)

x86 is the most common desktop/server CPU architecture. Its registers fall into the following categories:

Register TypeNameDescription
General-PurposeEAX (Accumulator)Used for arithmetic operations and function return values (e.g., ADD EAX, EBX).
EBX (Base Register)Often stores base addresses of data (e.g., array start address).
ECX (Counter)Loop counter (e.g., used by the LOOP instruction).
EDX (Data Register)Works with EAX for large-number operations (e.g., 64-bit multiplication).
Segment RegistersCS (Code Segment)Stores the segment base address of currently executing code (used with IP to compute physical address).
DS (Data Segment)Stores the segment base address for global/static data.
SS (Stack Segment)Stores the stack segment base address (used with SP to manage function call stacks).
ES/FS/GS (Extra Segments)Extended segment registers (rarely used in modern x86).
Pointer RegistersIP (Instruction Pointer)Stores the offset address of the next instruction to execute (combined with CS to get physical address).
SP (Stack Pointer)Stores the current top-of-stack offset address (automatically adjusted on push/pop).
BP (Base Pointer)Used to access local variables on the stack (e.g., function parameters).
Flags RegisterEFLAGSRecords status of the most recent operation (e.g., Carry Flag CF, Overflow Flag OF, Zero Flag ZF).

Evolution of General-Purpose Registers: From 16-bit to 64-bit

  • 16-bit Era (8086):
    General-purpose registers were 16-bit (AX, BX, CX, DX, SI, DI, BP, SP), supporting only 16-bit operations.
  • 32-bit Era (80386):
    Extended to 32-bit (EAX–ESP), supporting a 32-bit address space (4 GB) and 32-bit data operations.
  • 64-bit Era (x86-64):
    Introduced 64-bit registers (RAX–RSP), backward-compatible with 32-bit mode (accessing low 32 bits via EAX), and supports a much larger address space (theoretically 2⁶⁴ bytes).

Segment Registers in Protected Mode

New Roles of Segment Registers:

RegisterTraditional UseProtected Mode Function
CSCode SegmentPoints to code segment descriptor
DSData SegmentPoints to data segment descriptor
SSStack SegmentPoints to stack segment descriptor
ES/FS/GSExtra SegmentsFlexible data segment access

Segment Selector Structure:

15                 3   2   1   0
+------------------+---+---+
| Segment Index(13)| TI| RPL|
+------------------+---+---+
TI=0: Look up in GDT  
TI=1: Look up in LDT  
RPL: Requested Privilege Level (0–3)

Segment Registers in Real Mode (16-bit)

Real mode is the initial mode of the 8086/8088 CPU, using a segmented memory model:

  • Segment Base Address: Segment register value shifted left by 4 bits (e.g., CS=0x1234 → segment base = 0x12340).
  • Offset Address: 16-bit offset (e.g., IP=0x5678); physical address = segment base + offset (0x12340 + 0x5678 = 0x179B8).
  • Segment Register Types: CS (code), DS (data), SS (stack), ES (extra).

Segment Registers in Protected Mode (32-bit)

Protected mode, introduced with the 80386, is a modern memory management model that uses Segment Descriptor Tables (GDT/LDT) for flexible memory protection:

  • Segment Selector: Segment registers store a 16-bit selector (index + table indicator + privilege level), not the base address directly.
  • Segment Descriptor: An 8-byte entry in GDT/LDT containing segment base (32-bit), limit (20-bit), access rights (e.g., readable/writable/executable), etc.
  • Loading Segment Registers:
    Example: MOV AX, 0x08 (selects 1st descriptor in GDT) → MOV DS, AX loads the data segment base.

Example: Loading a Data Segment in Protected Mode

; GDT definition (assume GDT base at 0x00100000)
GDT_START:
    dq 0x0000000000000000          ; Null descriptor
    dq 0x00CF9A000000FFFF          ; Data segment descriptor (base=0x00000000, limit=4GB, readable/writable)
GDT_END:

; Load GDTR (points to GDT)
lgdt [gdt_descriptor]              ; gdt_descriptor holds GDT base and size

; Set DS register
mov ax, 0x0008                     ; Segment selector (index=1, RPL=0)
mov ds, ax                         ; DS base = GDT[1].base = 0x00000000

Pointer and Index Registers

Special-Purpose Registers:

  • ESP/RSP: Stack pointer (automatically adjusted)
  • EBP/RBP: Base pointer (for stack frame referencing)
  • ESI/EDI: Source/Destination pointers for string operations

Modern Extended Usage:

; Use R8–R15 as additional pointers
mov r8, [rsi + rcx*8]              ; 64-bit base + scaled index addressing
mov [r9 + rdx*4], r10d             ; Store 32-bit data

EFLAGS Register

EFLAGS (32-bit) records the result state of the most recent operation, used for conditional jumps (e.g., JZ, JC) and control flow decisions.

Key Flag Bits:

FlagNameFunction DescriptionTrigger Condition
CFCarry FlagUnsigned overflow (carry in addition, borrow in subtraction)ADD AX, BX → result > 0xFFFF → CF=1
PFParity FlagEven number of 1s in low 8 bits of resultADD AL, 3 → result low byte = 0xA (2 ones) → PF=1
AFAuxiliary CarryBCD carry from low 4 bitsADD AL, 0x0F → low 4 bits = 0x1E → AF=1
ZFZero FlagResult is zeroCMP EAX, EBX → EAX=EBX → ZF=1
SFSign FlagMSB (sign bit) is 1 (for signed numbers)SUB EAX, 100 → negative result → SF=1
OFOverflow FlagSigned overflow (result out of range)ADD EAX, EBX → EAX=0x7FFFFFFF, EBX=2 → OF=1
DFDirection FlagControls direction of string ops (LODSB, STOSB, etc.)STD → DF=1 (decrement SI/DI); CLD → DF=0 (increment)
IFInterrupt EnableCPU allows external interruptsCLI → IF=0 (disable); STI → IF=1 (enable)
TFTrap FlagSingle-step debug modeTRAP → TF=1 (interrupt after each instruction)

Conditional Jump Dependencies:

cmp eax, ebx
; After setting flags...
je  label    ; ZF=1
jg  label    ; SF=OF and ZF=0
jae label    ; CF=0

Register Usage Conventions

Calling Convention Example (cdecl):

RegisterPreserved by Callee?Purpose
EAXNoReturn value
ECX / EDXYesTemporary registers
EBX / ESI / EDI / EBPNoCallee-saved
ESPSpecialStack pointer

64-bit System V ABI:

  • Callee-saved: RBX, RBP, R12–R15
  • Caller-saved: RAX, RCX, RDX, RSI, RDI, R8–R11

Memory Management Mechanisms

Address Space Translation

Logical Address → Linear Address → Physical Address:

  • Segment Selector → Segment Descriptor → Segment Base
  • Offset + Segment Base = Linear Address
  • Page Table Translation → Physical Address

Paging Mechanism Key Structures

  • CR3: Page Directory Base Register
  • PDE (Page Directory Entry): 4 bytes per entry
  • PTE (Page Table Entry): 4 bytes per entry

Logical Address (Linear Address in Process View)

In protected mode, logical address is the process’s view of its address space (e.g., 0x00000000 ~ 0xFFFFFFFF for 32-bit processes):
Logical Address = Segment Base (from GDT/LDT) + Offset

Linear Address

Intermediate address after MMU translation (0x00000000 ~ 0xFFFFFFFF in 32-bit systems), further translated to physical address via page tables (if paging is enabled).

Physical Address

Actual hardware memory address (e.g., 0x00000000 ~ 0x7FFFFFFF for DDR4 RAM), formed by combining the Physical Frame Number (PFN) from PTE with page offset.

Translation Flow Example (32-bit with Paging Enabled):
Logical Address → Segment Base + Offset → Linear Address → Page Directory → Page Table → PFN + Page Offset → Physical Address

Memory Addressing Modes

Common Addressing Modes

Addressing ModeDescriptionExample
Immediate AddressingOperand embedded directly in instructionMOV EAX, 5 (EAX ← 5)
Register AddressingOperand in registerMOV EBX, EAX (EBX ← EAX)
Direct AddressingAbsolute memory address in instructionMOV EAX, [0x1000]
Register IndirectAddress in registerMOV EAX, [EBX]
Base + IndexAddress = base reg + index regMOV EAX, [EBX+ESI]
Relative AddressingAddress = current IP + offset (for jumps)JMP 0x10
Scaled Index (Base + Index × Scale)Address = base + index × scale (e.g., for arrays)MOV EAX, [EBX+ESI*4]

Performance Impact of Addressing Modes

  • Direct: Fixed address—good for globals, inflexible.
  • Register Indirect: Dynamic address—ideal for array traversal in loops (e.g., ESI as index).
  • Scaled Index: Ideal for multi-dimensional arrays (e.g., EBX = row base, ESI = column index × 4 for int).

Complex Addressing Examples:

; Base + scaled index
mov eax, [ebx + esi*4]

; Scaled index with displacement (32-bit)
mov ecx, [edx + edi*8 + 0x100]

; 64-bit addressing
mov rax, [r8 + r9*2 + 0x200]

Addressing Mode Encoding:

  • ModR/M Byte: Specifies addressing mode
  • SIB Byte: Handles complex addressing (Scale-Index-Base)

Stack Operation Principles

Stack Growth Direction

x86 stack grows downward (top address < bottom address):

  • PUSH: Decrement ESP by 4 (32-bit), store data at [ESP]
  • POP: Load data from [ESP], increment ESP by 4

Role of Stack in Function Calls

  • Save Return Address: CALL pushes next instruction address; RET pops and jumps.
  • Save Caller State: Called function saves caller’s EBP via PUSH EBP, sets up new stack frame.
  • Local Variable Storage: Allocated at [EBP-4], [EBP-8], etc.; freed via MOV ESP, EBP.

Function Call Stack Frame Layout:

High Address
-----------------
| Caller Arg N   |
| ...            |
| Caller Arg 1   |
| Return Address | <-- ESP before CALL
-----------------
| Saved EBP      | <-- Current EBP
| Local Var 1    |
| ...            |
| Local Var N    | <-- Current ESP
Low Address

Key Instruction Sequence:

push ebp          ; Save old frame
mov  ebp, esp     ; Set up new frame
sub  esp, N       ; Allocate locals
...               ; Function body
mov  esp, ebp     ; Deallocate locals
pop  ebp          ; Restore old frame
ret               ; Return

Memory Alignment Optimization

Reasons for Alignment

  • Hardware Requirement: Some CPUs (e.g., ARM) require aligned access or raise exceptions.
  • Performance: Aligned access needs one bus cycle; unaligned may need multiple (e.g., 4-byte data at 0x1 → two 2-byte accesses).

Alignment Rules

  • Natural Alignment: Data type aligned to its size (e.g., int (4B) → 4-byte aligned; double (8B) → 8-byte aligned).
  • Forced Alignment: Use align directive (e.g., align 16 for 16-byte alignment).

Programming Practices

  • Struct Alignment: Struct aligns to max member alignment (e.g., struct with double → 8-byte aligned).
struc Person
    name: resb 20    ; 20 bytes (1-byte aligned)
    age:  resd 1     ; 4 bytes (4-byte aligned → struct aligned to 4)
endstruc
  • Data Definition Alignment: Use ddq, dq to ensure alignment (e.g., ddq 0x123456789ABCDEF0 → 8-byte aligned).

Alignment Requirements:

  • 32-bit data: 4-byte aligned
  • 64-bit data: 8-byte aligned
  • SSE data: 16-byte aligned

Alignment Directives:

; GCC-style
.align 16

; NASM-style
section .data
    align 16
    dword_array dd 1,2,3,4

Performance Impact of Misalignment:

  • Reduced performance (multiple memory accesses)
  • Exceptions on some architectures

Memory Protection Mechanisms

Segment Protection (Protected Mode)

  • Descriptor Permissions: P (Present), DPL (Descriptor Privilege Level), Type control access (read/write/execute).
  • Bounds Checking: Segment Limit restricts offset range (e.g., limit=0xFFFF → max offset=0xFFFF → 64KB segment).

Page Protection (Virtual Memory)

  • PTE Permissions: R/W (Read/Write), U/S (User/Supervisor) control page access.
  • Page Fault: Accessing unmapped page triggers fault; OS loads data and updates page table.

Privilege Level Checks (Ring 0–Ring 3)

  • Ring 0: Kernel mode—full access to memory/hardware.
  • Ring 3: User mode—restricted to own memory and limited hardware.
  • System Calls: User programs switch privilege via INT 0x80 (Linux) or SYSENTER (x86-64).

Page-Level Protection Attributes:

AttributeValueFunction
PRESENT1Page is present
RW1Writable
USER1Accessible in user mode
NOEXEC1Not executable

Key System Calls:

// Linux memory management
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int mprotect(void *addr, size_t len, int prot);

Data Types and Operations

Integer Types

Signed Integers

  • Representation: Two’s complement (MSB = sign bit).
  • Instructions: ADD, SUB, IMUL (signed multiply), IDIV (signed divide).
  • Overflow Detection: OF flag (e.g., ADD AX, BX → OF=1 = signed overflow).

Unsigned Integers

  • Representation: Pure binary (no sign bit).
  • Instructions: ADD, SUB, MUL (unsigned multiply), DIV (unsigned divide).
  • Carry Detection: CF flag (e.g., ADD AX, BX → CF=1 = unsigned overflow).

Data Definition Directives:

db 0x12                 ; Define byte (8-bit)
dw 0x1234               ; Define word (16-bit)
dd 0x12345678           ; Define double-word (32-bit)
dq 0x123456789ABCDEF0   ; Define quad-word (64-bit)

Arithmetic Examples:

mov eax, 10
mov ebx, 3
div ebx        ; EAX=3, EDX=1 (remainder)
mul ecx        ; EDX:EAX = EAX * ECX

Floating-Point Handling

Floating-point numbers (float, double) are processed by dedicated FPU units. x86 supports x87 FPU (legacy) and SSE/AVX (modern).

x87 FPU Instructions

  • Data Types: 32-bit (float), 64-bit (double), 80-bit (extended precision).
  • Core Instructions: FLD (load), FADD (add), FMUL (multiply), FSTP (store and pop).
  • Example: Compute a + b (a=1.5, b=2.5)
section .data
    a dd 0x3FE00000    ; IEEE 754 single-precision for 1.5
    b dd 0x40000000    ; IEEE 754 single-precision for 2.5

section .text
    fld dword [a]      ; Load a → ST0
    fld dword [b]      ; Load b → ST0, a → ST1
    fadd st0, st1      ; ST0 = ST0 + ST1 (1.5 + 2.5 = 4.0)
    fstp dword [result]; Store and pop

SSE Instructions (Streaming SIMD Extensions)

  • Parallel Processing: SIMD—process multiple floats simultaneously (e.g., ADDPS adds 4×32-bit floats).
  • Use Cases: Graphics (OpenGL/DirectX), scientific computing (matrix ops).

x87 vs. SSE Examples:

; x87
fld dword [pi]
fadd st0, st1
fstp qword [result]

; SSE
movss xmm0, [float1]   ; Load single float
addss xmm0, [float2]   ; Add single float
movss [result], xmm0   ; Store result

String Handling

Strings (ASCII, UTF-8) stored as contiguous bytes; processed efficiently via string instructions (MOVS, CMPS, etc.).

Core String Instructions

InstructionFunctionExample
MOVSCopy string (MOVSB=byte, MOVSW=word, MOVSD=dword)MOVSB → copy [DS:ESI] to [ES:EDI]
CMPSCompare strings (CMPSB, CMPSW)CMPSB → compare [DS:ESI] and [ES:EDI]
SCASScan string (vs. AL/AX/EAX; SCASB=byte)SCASB → find byte equal to AL
STOSStore string (STOSB=store AL to [ES:EDI])STOSB → store AL to [ES:EDI]

Optimization Techniques

  • Direction Flag (DF): CLD (DF=0 → increment addresses), STD (DF=1 → decrement).
  • Repeat Prefix: REP MOVSB repeats until ECX=0 (efficient bulk copy).

ASCII String Example:

section .data
    msg db 'Hello', 0xA, 0

section .text
    mov esi, msg
    mov ecx, 5
print_loop:
    mov al, [esi]
    call putchar
    inc esi
    loop print_loop

Unicode Handling:

; UTF-16 string
msg dw 'H','e','l','l','o',0

; UTF-8 string ("hello")
msg db 0xE4,0xBD,0xA0,0xE5,0xA5,0xBD,0x0A,0

Data Transfer Optimization

Common operations (register ↔ memory); optimization reduces instruction count and execution time.

Avoid Redundant Loads

  • Reuse Registers: Keep frequently accessed data in registers.
; Inefficient: redundant load
mov eax, [data]
add eax, 10
mov [result], eax
mov eax, [data]    ; Redundant!
sub eax, 5
mov [result2], eax

; Efficient: reuse register
mov eax, [data]
add eax, 10
mov [result], eax
sub eax, 5
mov [result2], eax

Use Shift Instructions for Powers of Two

  • SHL EAX, 3 ≡ EAX × 8

MOV Variants:

movzx eax, byte [mem8]   ; Zero-extend byte to 32-bit
movsx ebx, byte [mem8]   ; Sign-extend byte to 32-bit
movd  xmm0, eax          ; Move 32-bit to XMM
movq  xmm1, [mem64]      ; Move 64-bit to XMM

XCHG Applications:

xchg eax, ebx            ; Register swap
xchg [mem32], ecx        ; Memory-register swap
lock xchg [mem32], eax   ; Atomic swap

Advanced Data Definition Techniques

Structures (Struct)

  • Definition: Use struc/endstruc; members stored sequentially.
  • Alignment: Struct aligns to max member alignment.
struc point
    .x resd 1
    .y resd 1
endstruc

section .data
    p1 point 10, 20

Array Initialization

array dd 1,2,3,4,5
times 10 dd 0    ; 10 dwords initialized to 0

Unions

  • Definition: Use union/endunion; members share same memory.
  • Use Case: Save memory (e.g., store int or float in same space); beware of type safety.

Example: Value Union

union Value
    .i: resd 1    ; 4 bytes (int)
    .f: resq 1    ; 8 bytes (double) → union size = 8 bytes (largest member)
endunion
Share your love