正如其他人所指出的,x86-64 的“jmp relative”指令仅限于 32 位有符号位移,用作相对于程序计数器的相对偏移量。
OP 询问为什么没有 64 位偏移的相对跳转。我不能代表英特尔的设计人员,但很明显,这条指令根本不会很有用,尤其是在 32 位相对 jmp 可用的情况下。唯一需要它的时候是您的程序大小超过 2 GB,因此 32 位相对 jmp 无法从其中的任何点到达所有它。最近看到过任何 2Gb 的目标文件吗?因此,此类指令的明显效用似乎非常小。
大多数情况下,当程序变得非常大时,它们开始被分解成更易于管理的元素,这些元素可以以不同的速度发展。(DLL 就是一个例子)。这些元素之间的接口是通过更神秘的方式(跳跃向量等)完成的,以确保接口在面对进化时保持不变。一个极长的 jmp relative 可用于从应用程序到达另一个模块中的入口点,但将绝对地址加载到寄存器并进行寄存器间接调用的实际成本在实践中足够小,以至于不值得优化。现代 CPU 设计就是要优化晶体管的放置位置,以最大限度地提高性能。
为了完整起见,x86(许多口味)也有非常短的 jmp 相对指令(8 位有符号偏移)。在实践中,即使是 32 位 jmp 相关指令也很少需要,特别是如果您有一个可以重新排列代码块的良好代码生成器。出于同样的原因,英特尔可能会忽略这些。我怀疑它们的效用稍微高到足以证明晶体管的合理性。
“大文字操作数”的问题在许多架构中以有趣的方式出现。如果您检查代码中文字值的分布,您会发现较小的值(0,1,ascii 字符代码)占相当大的百分比;几乎所有其他东西都是内存地址。所以你在程序中不需要“大字面值”,但你必须以某种方式处理内存地址。Sparc 芯片以“将文字值低加载到寄存器”(意思是“小常量”)而著称,而较少使用的“加载文字值高”(填充寄存器中的高位)用作第二条指令以生成大常量,并且使用较少。这使代码保持较小,除非您需要一个大常数;