2026-06-13
Stack Overflow: View Question
Tags: memory, x86, operating-system, memory-segmentation, gdt
Score: 0 | Views: 64
The asker is wrestling with a classic protected-mode confusion: how can CS, a mere 16-bit register, possibly address a Global Descriptor Table entry that lives somewhere in a 32-bit (4 GiB) physical address space? Intuitively, 16 bits gives you only 64 KiB of reach, which is nowhere near enough to point anywhere in RAM.
Why the confusion is reasonable. In real mode, CS really does hold a value that participates directly in address generation (CS << 4 + IP). It feels natural to assume the same model carries into protected mode, just bigger. It doesn't. The architecture pivots on a subtle but crucial change of meaning for the segment register.
The key insight: the segment register is not a pointer, it's an index. In protected mode, the 16 bits of CS are split into three fields:
So CS doesn't address RAM directly. It picks one of up to 8192 entries from a table whose actual base address lives in the GDTR register — and GDTR is a 48-bit beast (32-bit linear base + 16-bit limit), loaded by LGDT. That is where the 32-bit reach comes from. The CPU computes GDTR.base + (index × 8) to find the 8-byte descriptor, then caches the descriptor's base, limit, and access rights in a hidden part of CS.
Sketch of an answer to give them:
GDTR/LDTR, which are wider than 16 bits — that's how you reach anywhere in 32-bit space.Gotchas worth flagging:
DS/ES is legal but using it faults; loading into CS or SS faults immediately.CS/DS/ES/SS), but FS/GS keep their bases for TLS — a useful follow-up to mention.GDTR.
