完全な命令がx64 asmコードで必要とする最大バイト数はいくつですか?
アドレスへのジャンプのようなものは、私が仮定する最大9バイトを占める可能性があります:FF 00 00 00 00 11 12 3F 1Fしかし、それがx64命令が使用できる最大バイト数かどうかはわかりません
X86命令セット(16、32または64ビット、すべてのバリアント/モード)は、命令が最大15バイトであることを保証/要求します。それを超えると、「無効なオペコード」が生成されます。冗長なプレフィックス(たとえば、複数の0x66または0x67プレフィックスなど)を使用しないと、これを実現することはできません。
データ項目として実際に64ビットをとる唯一の命令は、登録するロード定数です(Intel構文:mov reg, 12345678ABCDEF00h
、at&t構文:movabs $12345678ABCDEF00, %reg
)-したがって、31ビットを超えて前後にジャンプしたい場合は、ターゲット位置をレジスターに移動してから、レジスターを呼び出し/ジャンプします。 32ビットの即値と変位(相対ジャンプおよびアドレッシングモード)を使用すると、64ビットモードの多くの命令で4バイトが節約されます。
質問はですが、x86命令セットで可能な最長の命令は何ですか?
回答:無限のバイト数で有効なx86命令を形成できます!
そうです、64K全体を埋めることができますROM単一の有効な命令で画像。より具体的には、 8086命令の長さクール!残念ながら、今日のi386バリアントは、15バイトを超える命令をデコードしようとすると、一般保護違反をスローします。
では、無限に長いが有効な8086命令はどのようなものでしょうか。ちょっと退屈だね。オペコードの前に冗長なプレフィックスを使用することによってのみ、無限に長い命令を形成できます。命令プレフィックスは、デフォルトのアドレスサイズ、データサイズ、または命令で使用されるセグメントレジスタを変更できる命令の先頭に付加されるバイトです。
たとえば、無害に見える命令を実行できます。
89 E5 mov %sp,%bp
そして、それを本当に長い命令に変えます:
66 66 66 66 … 66 66 89 E5 mov %sp,%bp
今、それはただの悪です。
https://web.archive.org/web/20131109063453/https://www.onlinedisassembler.com/blog/?p=2
場合によっては、従来の15バイトの長さ制限を超える有効な命令をエンコードすることが可能です。例えば:
; 16-bit mode F2 F0 36 66 67 81 84 24 disp32 imm32 = xaquire lock add [ss:esp*1+disp32],imm32 F3 F0 36 66 67 81 84 24 disp32 imm32 = xrelease lock add [ss:esp*1+disp32],imm32 ; 16-bit mode 36 67 8F EA 78 12 84 24 disp32 imm32 = lwpins eax,[ss:esp*1+disp32],imm32 36 67 8F EA 78 12 8C 24 disp32 imm32 = lwpval eax,[ss:esp*1+disp32],imm32 36 67 8F EA 78 10 84 24 disp32 imm32 = bextr eax,[ss:esp*1+disp32],imm32 ; 64-bit mode 64 67 8F EA F8 12 84 18 disp32 imm32 = lwpins rax,[fs:eax+ebx+disp32],imm32 64 67 8F EA F8 12 8C 18 disp32 imm32 = lwpval rax,[fs:eax+ebx+disp32],imm32 64 67 8F EA F8 10 84 18 disp32 imm32 = bextr rax,[fs:eax+ebx+disp32],imm32
インテル®64およびIA-32アーキテクチャーソフトウェア開発者向けマニュアルから:
2.3.11 AVX命令の長さ
Intel 64およびIA-32命令の最大長は15バイトのままです。
15バイト以上にエンコードする命令を作成できますが、そのような命令は違法であり、おそらく実行されません。