The absolutely minimal code to enter - and leave - protected mode is this:<p><pre><code> mov eax,cr0
inc ax ;sets bit 0, assuming it was clear
mov cr0,eax
dec ax ;clears bit 0
mov cr0,eax
</code></pre>
As the article correctly said, descriptor caches are what the CPU actually uses to access memory. Coming from real mode, the attributes are already set up the same as in privileged 16-bit protected mode (except that CS is writable), the limit is 64K, and the base is the segment number shifted left by 4, exactly what we require.<p>"But that's cheating!", some might say - not really, how else would it be possible to even execute one instruction in protected mode, if those registers weren't already initialized to a sane state? CS at the very least has to be, so that you can execute a jump to the "proper" protected mode segment right after loading CR0.<p>I remember reading some documentation that even said you can load GDT either before or after the "switch" to protected mode, which would be even more impossible if that somehow required different segments already set up.<p>If you want to be pedantic, there also has to be a jump in there to clear the prefetch queue and make sure the CPU actually interprets code according to the new mode, instead of the one that was active when the instruction was fetched and decoded. But that first jump can - and according to some Intel manuals, <i>must!</i> - actually be a near jump, staying in the same code segment at least for the moment. Since a lot of protected mode init code gets this wrong however, they had to keep support for a far jump as the first instruction as well, probably making the microcode for that instruction slower than it could have otherwise been.<p>(To enter "unreal mode", of course you do also need a GDT, but it doesn't need to have any descriptors other than one for the flat 4G data segment)