I\'ve got the code segment and the offset values stored in two registers, say AX
and BX
respectively. In NASM how can I encode a far call to AX:B
There isn't a way to encode a far call instruction where the segment and/or offset are in registers. The far call instruction requires that the destination either be given as an immediate operand that supplies both the segment and offset of the destination or a memory operand that does. So example only instructions like the following are valid:
call 0x1234:0x5678 ; immediate operand
call FAR far_func ; immediate operand
call FAR [far_fnptr] ; memory operand
call FAR [bp - 8] ; memory operand
So if you have the destination segment and offset in the AX and BX registers you'll need to store the value in memory some place before you can call the function the registers point to. So for example you could do something like the following:
push ax
push bx
mov bp, sp
call FAR [bp]
add sp, 4
Often back in the day the RETF instruction was used to do this:
push cs
push .return_here
push ax
push bx
retf
.return_here:
However on modern CPUs this has a significant performance penalty as it will cause the CPU's return stack buffer to generate incorrect branch predictions.
Here's one way of doing it:
push ax
push bx
retf
You have to put them in memory. You can’t perform a far call through registers. Assuming bp is set up as a frame pointer, you can use something like this:
push ax
push bx
call far [bp-N]
add sp, 4
(with a suitable value for N).