Techflash wrote:
As said previously:
Octocontrabass wrote:
There's no way to encode a far JMP with a 64-bit destination in long mode, so you'll have to use something else (far RET is the usual choice).
So a far jump won't work. Still working on that part.
UPDATE: Not sure if this would work or not, but potentially:
Code:
retf $0
might
Well, OK, I forgot about that. Yes, there is no direct far jump in 64-bit mode. But you can make an indirect far jump, or a far return. BTW, that is "lret" in AT&T. I have no idea what "retf" does, but not what you want for sure. In the position you have, I would encode it as this:
Code:
pushq $8 /* push CS selector to stack */
pushq 8(%rsp) /* now the return address from the function call */
lretq $8 /* now return there, clearing the old return address from the stack */
Since the number 8 makes an appearance multiple times here: The 8 in the first push is actually the CS selector. In the second push, it is the offset to the return address (which was 0 before the first push). And finally, in the lretq it gives the amount to adjust the stack pointer after removing the far pointer from the stack. After the two pushes, the stack is "<return address> - 8 - <return address>", and you need to clear that all out when returning. A normal lretq without operand would leave the old return address on stack, so increase the stack pointer by another 8 before returning. Thank god I used to write assembler programs for Windows, which is how I knew of the version of return with immediate operand.
You can of course also do something like
Code:
pushq $8
leaq 1f(%rip), %rax
pushq %rax
ljmpq *(%rsp)
1:
addq $16, %rsp
But that is longer and doesn't return from the function, so you need to add that as well. Ultimately your call.