Reputation: 661
This is a standard piece of code that switches the cpu into 32 bit mode..
cli
lgdt [gdt_descriptor] ; Assume a well-defined GDT
mov eax, cr0
or eax, 0x1
mov cr0, eax; Is this the exact moment when the processor switches to 32 bit mode?
jmp CODE_SEG:pipeline_flush ; Here CODE_SEG is 0x08,i.e, the segment descriptor after the NULL descriptor in the GDT
[bits 32]
pipeline_flush:
Here the far jump instruction is a 16 bit(?) encoded instruction.... but the processor is in 32 bit mode.... If I change the code to:
[bits 32]
jmp CODE_SEG:pipeline_flush
The code ceases to work...
Why is this??
Upvotes: 1
Views: 1918
Reputation: 12435
After setting bit 0 of CR0, the processor is in 16-bit protected mode, so instructions are executed as 16 bit instructions.
The BITS 32 directive causes the jmp instruction to be assembled with 32 bits for the offset part. The processor treats the upper 16 bits of the offset as the segment. Since it is not a valid code segment, it raises #GP.
Upvotes: 3