如何使用JMP模拟CALL指令? [英] How can I simulate a CALL instruction by using JMP?

查看:50
本文介绍了如何使用JMP模拟CALL指令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类似,但没有 CALL 指令.我想我应该使用 JMP 和其他可能的指令.

Like this but without the CALL instruction. I suppose that I should use JMP and probably other instructions.

PUSH 5
PUSH 4
CALL Function

推荐答案

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

This is fairly easy to do. Push the return address onto the stack and then jump to the subroutine. The final code looks like this:

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

 Function: 
   ...
   ret

这是可行的,但您实际上并不想这样做.在大多数现代处理器上,都保留了一个片上调用堆栈返回地址缓存,该缓存将调用中的返回地址压入一个调用中,并且在RET上弹出返回地址.在处理器上,这具有极短的更新/访问时间,这意味着RET指令可以使用调用堆栈缓存弹出的值来预测PC下一步应该去哪里,而不用等待从实际指向的内存位置读取实际的内存到ESP.如果您执行"PUSH offset label1"技巧,此缓存不会更新,因此RET分支预测是错误的,处理器流水线也变了,对性能产生了严重的负面影响.(我认为IBM拥有特殊指令的专利,这些特殊指令本质上是"PUSHRETURNADDRESS k"和"POPRETURNADDESS",因此可以在某些CPU上使用此技巧.las,不是在x86上.

While this works, you really don't want to do this. On most modern processors, an on-chip call stack return address cache is kept, which pushes return addresses on a call, and pops return addresses on an RET. Being on the processor this has extremely short update/access times, which means the RET instruction can use the call-stack cache popped value to predict where the PC should go next, rather than waiting for the actual memory read from the memory location actually pointed to by ESP. If you do the "PUSH offset label1" trick, this cache does not get updated, and thus the RET branch prediction is wrong and the processor pipeline gets blown, having a severe negative impact on performance. (I think IBM has a patent on special instructions which are essentially "PUSHRETURNADDRESS k" and "POPRETURNADDESS", allowing this trick to be used on some of their CPUs. Alas, not on the x86.

这篇关于如何使用JMP模拟CALL指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆