Reputation: 285
I have a situation where I have to jump to a far address in real mode, I have the segment value in fs
register and offset in gs
register, and during the jump I have to maintain the exact register content, I have come up with one idea as following,
mov bp, fs
shl ebp, 16
mov bp, gs
jmp ebp
assuming bp
, fs
and gs
is not read in the called destination, another way I just found in NASM far jump / far call in real mode and ASM code conventions and I can use,
push fs
push gs
retf
I am wondering which method I should use or if there is any other way to achieve this ? I don't have much skill in x86 assembly so please forgive my ignorance.
Regards,
Arka
Upvotes: 2
Views: 1993
Reputation: 364160
If performance matters, mismatched call/return pairs throw off the return-address predictor, leading to the equivalent of a branch mispredict on this retf and later returns. (If far call / far ret even participate in that; they might not, IDK.) Otherwise it's the obvious choice.
jmp ebp
is a near jump (doesn't change cs
) so that can't work. You'd be using the seg:off
as a 32-bit integer, setting EIP to that value, not CS:IP.
You need a far jump (jmp ptr16:16
or jmp m16:16
). The ptr16:16
version requires the target address to be encoded in the instruction (so it's not an indirect jump). The only indirect (variable-destination) far jump encoding available has the segment:offset pair in memory, not (a) register(s)
mov [mem], fs
mov [mem+2], gs
jmp far [mem]
syntax from https://courses.engr.illinois.edu/ece390/archive/spr2002/books/labmanual/inst-ref-jmp.html
push/push/retf
will be significantly smaller, and doesn't need a separate scratch space, so it's probably better. If performance matters, measure both ways.
The mem
space can be on the stack, or static storage. But if you need specific stack contents when reaching the destination, you might not be able to leave extra stuff on the stack, and using space below the stack wouldn't be safe. (And you can only address the stack using addressing modes like [bp-4]
, not relative to [sp]
, unless you're on a 386 for 32-bit addressing modes like jmp far [esp+4]
or whatever.)
Upvotes: 1