Page 1 of 1
Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 3:23 am
by Haroogan
There are 2 different ways to achieve it. So I'm going to post 2 different snippets respectively:
#1
Code: Select all
BITS 16
%define LinearAddress(SegmentAddress,OffsetAddress) SegmentAddress * 0x10 + OffsetAddress
Code16:
...
JMP 8:LinearAddress(BootLoader2.SEGMENT_ADDRESS,Code32)
BITS 32
Code32:
...
#2
Code: Select all
BITS 16
%define LinearAddress(SegmentAddress,OffsetAddress) SegmentAddress * 0x10 + OffsetAddress
%macro JMP32 2
DB 0x66
DB 0xEA
DD %2;Address
DW %1;Selector
%endmacro
Code16:
...
JMP32 8,LinearAddress(BootLoader2.SEGMENT_ADDRESS,Code32)
BITS 32
Code32:
...
Both of them work just fine. But I've noticed that the
2nd one occupies more memory. So the
2nd one is really the 32 bit jump and the
1st one is not. But some people still recommend the
1st one and others - the
2nd one. Which one should I choose? And why? What's the essence of their difference?
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 4:10 am
by egos
#2 of course if destination code segment is 32-bit. There is a probability that high word of eip is not equal to zero.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 5:07 am
by Owen
egos wrote:#2 of course if destination code segment is 32-bit. There is a probability that high word of eip is not equal to zero.
Utter junk. Both 32-bit and 64-bit jumps set the full width of EIP
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 5:14 am
by egos
And what about 16-bit jump
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 5:33 am
by Owen
It zeros out the upper bits of rIP. If the upper bits were not zeroed, you would violate the segment limit...
A good assembler will therefore detect when the address will fit in 16-bits and use the 16-bit version of the jump
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 6:11 am
by egos
Owen wrote:It zeros out the upper bits of rIP.
Maybe in emulators but not in real CPUs.
If the upper bits were not zeroed, you would violate the segment limit...
CPU ignores high word of eip while executing 16-bit code therefore an error doesn't occur.
A good assembler will therefore detect when the address will fit in 16-bits and use the 16-bit version of the jump
And this behaviour will be fatal if high word of eip during execution is not equal to zero. To jump from 16-bit code to 32-bit code you should use forced 32-bit far jump anywhere except if you sure that eip.31-16=0 (or if you want to jump to eip.31-16 shl 16 + 16-bit destination offset
).
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 6:51 am
by Owen
If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.
This is from the Intel manuals, volume 2A, at time of writing page 3-554.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 8:20 am
by Haroogan
Anyway, I believe #2 is safer and more stable.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 9:48 am
by egos
Owen wrote:If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.
This is from the Intel manuals, volume 2A, at time of writing page 3-554.
Good argument but you didn't take into account that some people make CPUs and another write manuals for them. Also I can assume that behaviour of CPUs can change from one model to another. I tested some Pentium processors and they worked precisely as I said above.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 11:22 am
by Owen
egos wrote:This is from the Intel manuals, volume 2A, at time of writing page 3-554.
Good argument but you didn't take into account that some people make CPUs and another write manuals for them. Also I can assume that behaviour of CPUs can change from one model to another. I tested some Pentium processors and they worked precisely as I said above.
The behavior of the instruction is architecturally defined. It cannot change from one processor model to another. Can you cite a reference on a processor having the bug you mentioned? I fail to believe that such a bug would not be documented anywhere on the internet, particularly when the Pentium dates back to the days of segmented software. I certainly can't find it in Intel's Pentium errata sheet.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 12:52 pm
by egos
It was long time ago when I used 16-bit far jump to enter PM and recommended to other people to do so
Code: Select all
; fasm syntax
if Startup32<10000h
jmp KCODE:Startup32
else
jmp fword KCODE:Startup32
end if
When I saw what happened when eip.31-16 != 0 on my testing computer (probably it was same one that I have now) I was shocked
Now I have Intel Pentium MMX for testing. We can write testing code here and then test old and modern (I have Intel Core2 Quad Q9300 and Intel i7 920 at home too) CPUs with it.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 12:59 pm
by xenos
I guess you really disliked that 32 bit jump when you wrote "fword" instead of "dword"...
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 1:05 pm
by egos
In fasm syntax fword (or pword) means six-byte pointer. "dword" in this case (in 16-bit code) is default and means four-byte pointer.
Re: Details of the Far JMP into Protected Mode
Posted: Fri Aug 12, 2011 2:01 pm
by xenos
Ah, sorry, you're right - I haven't used fasm for a very long time... I was thinking about something like "ljmpl" in GNU as syntax, or the even more similar "jmp dword Seg:Off" in NASM syntax...