1

Is the 64-bit x86 asm sequence:

pop r11
jmp r11

... equivalent to near ret, except that it clobbers r11?

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • 2
    It may not be Win64 ABI compliant for a non-leaf function, but that's not inherent to the semantics – harold May 23 '18 at 00:16
  • In 64-bit mode, only `C3` (near return) is functionally equivalent to `pop` followed by `FF /4` (jump near absolute indirect). Other variants are not necessarily equivalent. – Hadi Brais May 23 '18 at 01:01
  • 1
    @harold - good point, although in my case I was asking it in the context of someone trying to [hack together their own coroutines](https://stackoverflow.com/q/50429345/149138), so I think they are pretty much SOL on the proper SEH handling anyways. – BeeOnRope May 23 '18 at 01:55
  • @HadiBrais - thanks, I meant near return and update the question to reflect that. – BeeOnRope May 23 '18 at 01:55
  • Architecturally, sure, unless you put prefixes in front of it. (e.g. operand-size can turn it into `pop r11w`, but IIRC `ret`'s operand-size is fixed at 64 and would be unaffected by a `66` prefix). Microarchitecturally, obviously not (and that's the whole point). – Peter Cordes May 23 '18 at 11:13

1 Answers1

1

Generally, the near return C3 is functionally equivalent to pop reg followed by a jump of the form FF /4 reg(jump near absolute indirect). They both pop a 64-bit value of the top of the stack into RIP. They also both may raise the same exceptions in the same situation in 64-bit mode. In particular, when the load from stack is to a non-canonical address, #SS(0) occurs. Also when the new RIP value is to a non-canonical address, #GP(0) occurs. Moreover, #PF and #AC(0) may be raised on any memory access. So if there is a possibility that one of these exceptions may occur and if the code handling the exception may behave differently depending on the instruction sequence used, then they would actually not be functionally equivalent, precisely speaking. I assume that there is some free GPR, such as r11. Otherwise, if freeing a register is necessary by spilling one to memory, then such process may have an impact on the architectural state that would not have occurred by simply using C3.

Hadi Brais
  • 22,259
  • 3
  • 54
  • 95