如何使用JMP模拟CALL指令?

cdo*_*nts 0 x86 assembly function

像这样,但没有CALL指示.我想我应该使用JMP,可能还有其他说明.

PUSH 5
PUSH 4
CALL Function
Run Code Online (Sandbox Code Playgroud)

Ira*_*ter 13

这很容易做到.将返回地址压入堆栈,然后跳转到子例程.最终代码如下所示:

   PUSH 5
   PUSH 4
   PUSH offset label1
   jmp Function
 label1: ; returns here
   leas esp, 8[esp]

 Function: 
   ...
   ret
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但你真的不想这样做. 在大多数现代处理器上,保留了片上调用堆栈返回地址缓存,它在调用时推送返回地址,并在RET上弹出返回地址.在处理器上,这具有极短的更新/访问时间,这意味着RET指令可以使用调用堆栈高速缓存弹出值来预测PC下一步应该去哪里,而不是等待从实际指向的内存位置读取的实际内存通过ESP.如果您执行"PUSH offset label1"技巧,则此缓存不会更新,因此RET分支预测错误,处理器管道崩溃,对性能产生严重的负面影响.(我认为IBM拥有特殊指令的专利,基本上是"PUSHRETURNADDRESS k"和"POPRETURNADDESS",允许在他们的一些CPU上使用这个技巧.唉,不在x86上.