Unreal Mode
Unreal mode is a technique for reaching memory above the 1 MB ceiling real mode normally imposes, without performing the full transition into protected mode that would otherwise be required to do so. It exploits a detail of how the CPU actually implements segment loading rather than any officially documented mode of its own, common in hand-written bootloaders that need to touch memory past 1 MB briefly (copying a kernel image to its final load address, for instance) before performing the real, full transition later at the boot stage that transition normally happens at.
What actually happens on a segment load
Section titled “What actually happens on a segment load”Every segment register load, in any mode, causes the CPU to read the corresponding descriptor from whatever table is currently active and cache that descriptor’s base, limit, and access rights internally; only that cached copy, not a fresh table lookup, is consulted on each subsequent memory access using that segment, which is why real mode’s own segment × 16 + offset computation coexists with this caching mechanism without normally being visible as two separate things at all.
; still in real mode throughout: PE bit is never touchedlgdt [gdt_descriptor] ; load a GDT containing a flat 32-bit data descriptor
mov eax, cr0or al, 1 ; briefly set PEmov cr0, eax
mov bx, FLAT_DATA_SEL ; load the 32-bit descriptor into a segment registermov ds, bx ; -- descriptor's 4 GB limit is now cached in the DS "shadow"
and al, 0xFE ; clear PE again, back to real modemov cr0, eaxLoading a segment register with a selector while briefly in protected mode caches that selector’s full 32-bit base and 4 GB limit from its GDT descriptor into the segment register’s hidden portion; clearing CR0.PE again afterward returns the CPU to interpreting that same segment register as an ordinary real-mode segment value for the purpose of address computation, but does not itself reload or reset the cached descriptor information sitting behind it.
The effect: a real-mode segment with a protected-mode limit
Section titled “The effect: a real-mode segment with a protected-mode limit”The consequence is a segment register that still behaves like real mode for address computation (segment × 16 + offset), while the CPU’s memory-access hardware continues enforcing the 4 GB limit cached from the earlier protected-mode load rather than real mode’s usual 64 KB segment limit, letting code compute addresses the ordinary real-mode way while still successfully reading and writing far past what real mode alone would ever permit. This is exactly the loophole unreal mode depends on: nothing about entering or leaving protected mode itself is what grants access to memory above 1 MB; it’s specifically the stale cached limit left behind in a segment register that was briefly loaded while protected mode was active, a side effect of how the CPU caches descriptor state rather than a documented, intentional real-mode extension.
Why this counts as a side effect, not a mode
Section titled “Why this counts as a side effect, not a mode”Intel’s own architecture manuals describe exactly two operating modes relevant here, real and protected, with nothing in between; “unreal mode” names a specific, reproducible consequence of the CPU’s segment-caching implementation, not a third mode the processor itself recognizes or documents as a deliberate feature. Nothing guarantees this caching behavior is preserved identically across every implementation or every future CPU generation the way an officially specified mode’s behavior would be, which is part of why code relying on it is generally treated as using a well-known but unofficial trick, useful and broadly reliable in practice on real x86 hardware and in essentially every emulator, but not something the architecture itself formally commits to supporting.
Implementation notes
Section titled “Implementation notes”The technique’s usefulness is limited specifically to data segments (DS, ES, FS, GS, SS): CS cannot be given the same treatment for code execution, since instruction fetching and decoding in real mode still follow real mode’s own 16-bit rules regardless of any cached limit sitting behind CS, meaning unreal mode extends addressable data range without extending the code a CPU running in real mode can actually execute past 16-bit encoding. Because unreal mode’s cached state lives in the otherwise-invisible hidden portion of a segment register, any subsequent segment reload from a real-mode value (an interrupt handler that reloads DS from a fixed real-mode segment value, for instance) silently discards the cached 4 GB limit and reverts that register to an ordinary 64 KB real-mode segment, a common source of code that works until some unrelated interrupt or subroutine call clobbers the very segment register the trick depended on.
References
Section titled “References”- ^ Intel, Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, Chapter 3.4.3: describes the segment descriptor cache (the “hidden” portion of a segment register) this technique depends on.
See also
Section titled “See also”- Protected Mode: the full transition this trick avoids performing, and the descriptor tables its own segment loads read from.
- The Boot Process: the boot stage, inside a hand-written bootloader, where this technique typically appears.