jump far after setting up protected mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Gigasoft
Member
Member
Posts: 858
Joined: Sat Nov 21, 2009 5:11 pm

Re: jump far after setting up protected mode

Post by Gigasoft »

In that case, the problem lies with the common source of misinformation which has given practically everyone who visits this site a flawed understanding of the x86 architecture. It is probably either the wiki, or some recommended link people will click on, or maybe some top result on google. The author of the tutorial you are following seems to be hopelessly confused himself. This probably originates back in the day when the internet was in its beginnings and you couldn't just download the manual.

In protected mode (CR0.PM=1 and EFLAGS.VM=0), instructions that load segment registers will interpret the operand as a GDT or LDT selector, and IDTR points to a table of interrupt descriptors. In real mode or virtual 8086 mode (CR0.PM=0 or EFLAGS.VM=1), loading a segment register will set the segment base equal to the selector shifted left by 4, and IDTR points to a table of 16-bit far pointers. That's the main difference.

The D/B field of the current CS determines the encoding of operand and address sizes. All it does is that when clear, they are 16-bit when no prefix is present, and 66h and 67h prefixes change the operand size or address size to 32 bits, respectively. When set, it's the other way around.

The D/B field of the current SS determines whether SP or ESP is used for stack operations.

The D/B field of an expand-down data segment determines whether the upper limit is 0ffffh or 0ffffffffh. Expand-down data segments are rarely used.

It just so happens that the D/B field of all segment registers is cleared on reset, and every limit is set to 0ffffh, and they are inaccessible in real mode. Therefore, to use a default size of 32 bits, as well as offsets greater than 0ffffh, you would have to enter protected mode first. In the process of copy pasting tutorials, which was a popular thing to do back then, some kids therefore conflated the various mechanisms involved, resulting in a lot of people being confused even to this day.
Octocontrabass
Member
Member
Posts: 5878
Joined: Mon Mar 25, 2013 7:01 pm

Re: jump far after setting up protected mode

Post by Octocontrabass »

slammar wrote:If the jump instructions comes before the 32 bits directive it works even though at this point the jump instruction itself should be executing in p-mode.
To summarize Gigasoft's post: setting bit 0 of CR0 does not put the processor in 32-bit mode. Performing a far jump to a 32-bit code segment puts the processor in 32-bit mode.

I'll see about adding this to our list of known issues in the Brokenthorn tutorial.
PeterX wrote:Shouldn't it be "jmp gdt_code-gdt_start: dword next_instruction"?
We already know the destination address fits within 16 bits, so there is no need to override the default operand size. It would be necessary if the destination address might not fit within 16 bits.
kzinti wrote:the offset is "0x2800". The offset for the 32 bits jump is "0x2A000000"
It's little-endian, so 0x28 and 0x2A, a difference of two bytes.
Post Reply