他の人が指摘したように、x86-64の「jmp relative」命令は、プログラムカウンターに対する相対オフセットとして使用される32ビットの符号付き変位に制限されています。
OPは、64ビットオフセットで相対ジャンプがない理由を尋ねました。Intel の設計者を代弁することはできませんが、特に 32 ビットの相対 jmp が利用できる場合、この命令があまり役に立たないことは明らかです。これが必要になるのは、プログラムのサイズが 2 GB 以上で、32 ビットの相対 jmp がプログラム内のどのポイントからもすべてに到達できない場合のみです。最近、2Gb のオブジェクト ファイルを見ましたか? したがって、そのような命令の明らかな有用性は非常に小さいようです。
ほとんどの場合、プログラムが非常に大きくなると、さまざまな速度で進化できる、より管理しやすい要素に分割され始めます。(DLL はこの例です)。そのような要素間のインターフェースは、より難解な手段 (ジャンプベクトルなど) によって行われ、進化に直面してもインターフェースが一定に保たれるようにします。非常に長い jmp 相対を使用して、アプリケーションから別のモジュールのエントリ ポイントに到達できますが、絶対アドレスをレジスタにロードしてレジスタ間接呼び出しを実行する実際のコストは、実際には十分小さいため、最適化する価値はありません。そして、最新の CPU 設計は、パフォーマンスを最大化するためにトランジスタを配置する場所を最適化することがすべてです。
完全を期すために、x86 (多くのフレーバー) にも非常に短い jmp 相対命令 (8 ビットの符号付きオフセット) があります。実際には、特にコード ブロックを再配置できる優れたコード ジェネレーターがある場合は、32 ビットの jmp 相対命令でさえほとんど必要ありません。インテルはおそらく、同じ理由でこれらを除外できたはずです。それらの有用性は、トランジスタを正当化するのに十分高いと思います。
「大きなリテラル オペランド」の問題は、多くのアーキテクチャで面白い形で現れます。コード内のリテラル値の分布を調べると、小さな値 (0、1、ASCII 文字コード) がかなりの割合を占めていることがわかります。他のほとんどすべてはメモリアドレスです。したがって、プログラムで「大きなリテラル値」は必要ありませんが、何らかの方法でメモリアドレスを処理する必要があります。Sparc チップには、「レジスタへの下位のリテラル値のロード」(「小さな定数」を意味する) と、あまり使用されない「上位のリテラル値のロード」(レジスタの上位ビットを埋める) があり、大きな定数を作成するための 2 番目の命令として使用されます。あまり使用されません。これにより、大きな定数が必要な場合を除いて、コードが小さく保たれます。