正如其他人指出,对于X86-64“相对的jmp”指令被限制在32位带符号的位移,作为相对于相对于程序计数器的偏移。
OP问为什么有一个64位无相对跳转偏移。我不能为英特尔的设计人员说话,但看起来很明显,这条指令不会很有用,特别是在32位相对jmp的可用性方面。唯一需要的是当你的程序的大小为2G时,以便32位相对jmp无法从其中的任何一点到达它。最近看到任何2Gb目标文件?所以这种说明的显然效用似乎很小。
大多数时候,程序得到真正的大,他们一开始就被分解成可以以不同的速度发展更易于管理的要素。 (DLL是这方面的一个例子)。这些元素之间的接口是通过更加神秘的手段(跳转向量等)完成的,以确保接口在进化过程中保持不变。一个非常长的jmp亲戚可以用来从应用程序到达另一个模块的入口点,但将绝对地址加载到寄存器并进行寄存器间接调用的实际成本足够小,在实践中它足够小值得优化。现代的CPU设计都是关于优化晶体管放置位置以最大限度地提高性能。
只要是完整的,在x86(许多种)有很短的JMP相对指令(8位有符号偏移量),太。实际上,即使是32位jmp相对指令也很少需要,特别是如果你有一个好的代码生成器可以重新安排代码块。英特尔可能会出于同样的原因而放弃这些。我怀疑它们的效用足够高以证明晶体管的合理性。
“大字面操作数”的问题在许多架构中以有趣的方式出现。如果您检查代码中文字值的分布,您会发现小值(0,1,ascii字符代码)涵盖了相当不错的百分比;几乎所有的东西都是内存地址。所以你在程序中不需要“大的字面值”,但你必须以某种方式处理内存地址。 Sparc芯片着名的有“将字面值低加载到寄存器中”(意思是“小常量”),并且较少使用“加载字面值高”(填充寄存器中的高位)作为第二条指令来产生大常数,使用较少。这使代码变得很小,除非你需要一个很大的常量;小代码意味着更高的指令取指速率,并有助于提高性能。
跳转指令具有32位偏移版本。如果偏移量符合32位,则可以使用32位偏移版本并保存几个字节(通过64位绝对地址或其他)。 –
感谢您的评论。 64位偏移版本的指令是什么? – WindChaser
我不相信有一个64位的偏移版本。 –