x64:如何做相对 jmp *%rax? [英] x64: How to do a relative jmp *%rax?

查看:26
本文介绍了x64:如何做相对 jmp *%rax?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编码一个 64 位相对跳转到存储在 x64 程序集中的 %rax 中的地址.AFAIK,这个没有操作码,所以我手动计算相对地址的对应绝对地址,然后我绝对跳转到绝对地址:

I want to encode a 64 bit relative jump to the address stored in %rax in x64 assembly. AFAIK, there is no opcode for this, so I calculate the corresponding absolute address for the relative address manually and then I do an absolute jump to the absolute address:

# destination address, relative to end of jmp instruction, is stored in %rax
00007ffff7ff6020: 0x0000488d1505000000   lea 0x5(%rip),%rdx # load %rip+5 (rip + size of add and jmpq) into %rdx
00007ffff7ff6027: 0x0000000000004801d0   add %rdx,%rax # calculate absolute address based on %rdx (behind jmpq) and %rax (the relative address)
00007ffff7ff602a: 0x00000000000000ffe0   jmpq *%rax # do an absolute jump to absolute address

但这对我来说看起来不必要地复杂.有没有更好的方法,指令更少?或者还有其他原因为什么应该避免 64 位相对跳转?

But this looks unnecessarily complex to me. Is there a better way with less instructions? Or is there another reason why 64 bit relative jumps should be avoided?

推荐答案

应该避免 64 位相对跳转,因为 jmp rel32 直接跳转的 +-2GiB 代码大小范围通常是足够的范围.

64-bit relative jumps should be avoided because the +-2GiB code-size range for jmp rel32 direct jumps is normally plenty of range.

如果你的目标距离更远,你通常只知道绝对地址,并且一开始就不应该计算 64 位相对位移.

If your target is farther away, you normally just know the absolute address, and shouldn't have calculated a 64-bit relative displacement in the first place.

只有当位移是链接时间常数时,相对位移才有意义,在这种情况下,您(链接器)通常将源和目标放置在彼此相距 2GiB 的范围内,因此您可以使用 <代码>jmp rel32.

Relative displacements only make sense when the displacement is a link-time constant, in which case you (the linker) are normally placing the source and target within 2GiB of each other so you can use jmp rel32.

如果你不能这样做,那么通常你会使用(对于一个巨大的"代码模型,其中其他地址被假定为 > 32 位) movabs $imm64, %rax/jmp *%rax.不过,这仍然很糟糕.(而且它不是位置无关的,所以如果你想随机化它的加载地址,你需要一个 64 位绝对目标地址的加载时间修正.Linux 上的 ELF 等可执行文件格式确实支持,所以即使在 PIE 可执行文件或 PIC 共享库代码中,您也可以在跳转表中使用 64 位绝对地址.)

If you can't do that, then normally you would use (for a "huge" code model where other addresses are assumed to be > 32 bits away) movabs $imm64, %rax / jmp *%rax. This still sucks a lot, though. (And it's not position-independent, so if you wanted to randomize its load address, you'd need a load-time fixup for the 64-bit absolute target address. Executable file formats like ELF on Linux do support that, though, so you can use 64-bit absolute addresses in jump tables even in PIE executables or PIC shared library code.)

这篇关于x64:如何做相对 jmp *%rax?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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