当您需要调用>的函数时会发生什么? 2 ^ 32位了吗?

时间:2015-08-04 20:47:08

标签: assembly linker x86 masm

我刚刚发现调用指令,我们通常实际上是程序计数器相对的。然而,x86指令使用32位宽偏移量来指示相对数字。

如果我想跳转怎么办? 4GB之外?

2 个答案:

答案 0 :(得分:1)

我想如果你将一些代码JIT分配到距离需要调用的某些函数超过2 ^ 32的缓冲区中,就会出现这种情况。简单的答案是:不要这样做。

在Linux上,例如,如果您希望JITed代码在主可执行文件中mmap(MAP_32BIT)运行,请使用call在低2GiB的虚拟地址空间中分配内存。 (假设一个与位置相关的可执行文件)。

在PIE可执行文件或共享库(通常无法映射到虚拟地址空间的低32位)中,您可以尝试通过尝试mmap <来在您自己的代码附近分配内存em>没有 MAP_FIXEDtrying different addresses in range if that doesn't work the first timemmap(hint_address, ...) /检查它是否在代码和/或数据的+ -2GiB范围内,达到/ munmap并使用不同的提示重试。

原因是唯一的解决方法是使用绝对地址间接调用。见Call an absolute pointer in x86 machine code。您需要将目标地址加载到寄存器中,或将地址作为指针存储在内存中,然后跳转到该地址。请参阅英特尔的insn参考手册,其中all the available encodings of call are listed.

x86 tag wiki链接指向https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

如果您不需要它超级高效,实际JIT绝对间接调用的一种方法是将指针表放在相对于JITed代码的已知位置,以便它可以使用间接call [rel pointer_to_func1](RIP相对寻址)。这类似于Unix共享库使用的全局偏移表,以及编译器生成的代码如果使用gcc -fno-plt编译时如何调用共享库函数。

答案 1 :(得分:0)

我碰巧有这个非常需要:在一些动态创建的代码中发出一个绝对的64位地址的调用,结果证明并不是很难,虽然与我们的直接绝对跳转相比有点笨拙在32位模式下(您的确切asm语法可能会有所不同,具体取决于您碰巧使用的汇编程序),例如:

.error