flat assembler
Message board for the users of flat assembler.

Index > Main > Problem in jumping to high addresses in 16bit protected mode

Author
Thread Post new topic Reply to topic
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 25 Dec 2023, 19:18
At boot, I am in 16bit protected mode after int 1589h.
The code selector in CS is 48 and is 16bit, 2GB size.
I am in the lower 64k. I want to jump over it, still remaining in 16bit mode. I am using USE16 directive.
If I use

jmp pword 48: 12345678h

it works, reloading CS with the same selector. But if I use

jmp dword 12345678h

it assembles fine but the program crashes.
Post 25 Dec 2023, 19:18
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 25 Dec 2023, 21:11
use16 - directive to the fasm to create 16-bit code. It does not change the processor settings according to this code.

After calling the int 15h function 89h, a new selector from the newly installed GDT must be loaded into CS. The first command sets and, accordingly, loads new limits into the shadow part of the segment register. And the second one does not do this, but just tries to jump into nowhere.

ADD: Switch to PM of the processor, you do not need to call the int 15h function 89h. You might as well save the GDT value and load a new one.
Code:
sgdt pword [old_gdt]
lgdt pword [new_gdt]
; Then turn off interrupts, including unmasked ones, and set 0 bit in CR0
cli
mov al, 8Fh
out 70h, al
mov al, 5
out 71h, al

mov eax, cr0
or al, 1
mov cr0, eax ; Now you can switch to protected mode.

jmp 0x30:12345678h ; real switch    

The last jmp command loads an 8-byte descriptor from GDT (from memory) with an offset of 0x30 from its beginning into the shadow part of the segment register (in the CPU).

Further, the processor can already work with a segment longer than 64 KB. Such limits are set in the shadow part of the segment registers after switching on in real mode.
Post 25 Dec 2023, 21:11
View user's profile Send private message Reply with quote
pfranz



Joined: 13 Jan 2007
Posts: 116
Location: Italy
pfranz 27 Dec 2023, 17:00
My bad, jmp dword didn't work simply because I had set a wrong ORG so the assembler would compute the wrong displacement for the relative jump.
Setting the right ORG fixes the 2nd jump.

By the way, I read in the Intel specification that EIP is loaded with 0000FFF0 at initialization. Is it guaranteed that at BIOS boot, the high 16 bits of EIP are 0 ?
Post 27 Dec 2023, 17:00
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 27 Dec 2023, 18:32
Quote:
Is it guaranteed that at BIOS boot, the high 16 bits of EIP are 0 ?
Yes. Because there is no separate EIP, RIP or IP for different addressing modes. There is one register and a hardware mechanism that ensures that its value does not exceed the limits in the shadow part of the segment register. Of course, if the upper part contains nonzero bits, then you will get an #GP exception. In order to avoid spurious exception triggers when the protection mechanism (PE) is disabled, the higher part of RIP is maintained in the zero state. To set the upper four bits in real mode (RM), the value of the visible part of the segment register is used, which is set to segment 15 (0xF000) => 0xF000 * 0x10 + 0xFFF0 = 0xFFFF0
Post 27 Dec 2023, 18:32
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.