Page 1 of 1
Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 7:01 pm
by ScropTheOSAdventurer
I am working on re-implementing my GDT code, and I was wondering: can the offset in a far jump come from a register (I mean like offset:address in this case)? I have looked on the web, but I can't find any answer for this on the web, so I am sorry if it is obvious.
Re: Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 7:10 pm
by bluemoon
use indirect jump, which you store the address in a memory location and dereference it.
Re: Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 7:12 pm
by ScropTheOSAdventurer
Just to make sure, in GAS syntax (forgive me if it is bad; still learning to work with GAS instead of Intel) it is so:
Code: Select all
jmp (addressofoffsetmemory):thetarget
Re: Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 7:32 pm
by sortie
I recall there being a useful popf instruction.
Re: Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 7:37 pm
by bluemoon
sortie wrote:I recall there being a useful popf instruction.
you mean retf? While it works well to reload GDT in 32bit and earlier arch, sadly retf has some problem with 64bit arch (which you use iretq instead).
Re: Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 7:47 pm
by ScropTheOSAdventurer
Well, what I said in the last post I gave doesn't assemble. Here are two messages:
GDTAssembly.s:16: Error: junk `:*' after expression
GDTAssembly.s:16: Warning: indirect jmp without `*'
In any case, I will look into retf.
Re: Any way for offset to not be hard-coded for far jump?
Posted: Tue May 27, 2014 8:06 pm
by ScropTheOSAdventurer
Here is the best explanation that I can find on the web for retf :
Far returns pop the IP followed by the CS, while near
returns pop only the IP register.
So does this mean that right before I call the function I push the offset, or while I am in the function I push it? In other words, is the new CS value on top of IP or BELOW it (assuming you think of the stack as going UPWARDS, although it doesn't)?
Re: Any way for offset to not be hard-coded for far jump?
Posted: Wed May 28, 2014 1:50 am
by alexfru
You could always dust off your favorite Intel or AMD manual (or google.com) and see the pseudo code for RETF. But, in case you can't find your duster, you first push CS (zero extended to 4 bytes if you're in 32-bit mode or the target is 32-bit code), then (E)IP, then do RETF (prefixed with db 0x66, if you're switching from 16-bit to 32-bit code). IRET can be used similarly.
Another option is to have a JMPF selector:offset instruction and patch the offset in it before executing it.
Re: Any way for offset to not be hard-coded for far jump?
Posted: Wed May 28, 2014 1:53 am
by ScropTheOSAdventurer
I should have read the manual instead of googling. In any case, I pretty much implemented what you just told me (except that I wrongly assumed cs was in 16 bits instead of 32, which explains my triple fault). Thanks!
Re: Any way for offset to not be hard-coded for far jump?
Posted: Wed May 28, 2014 3:24 am
by ScropTheOSAdventurer
Ok, here is the code I finally settled on (it works). You would call it in C like this
Code: Select all
load_gdt(gdtpointerstruct, dataoffsetingdt, codeoffsetingdt);
Now the implementation:
Code: Select all
Reload_CS:
retf
.global load_gdt
.type load_gdt, @function
load_gdt:
xor %edx, %edx
movw 16(%esp), %dx
movw 12(%esp), %ax
lgdt 4(%esp)
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
push %edx
call Reload_CS
ret
Thanks guys!