次の x86-32 命令を想定します。
add ebx,1
このオペコードを組み立てるには、(少なくとも) 2 つの方法があります。
81 c3 01 00 00 00
また
83 c3 01
1 つ目は 1 を 4 バイトの dword として保持し、2 つ目は 1 をバイトとして保持します。
1を2バイトとして保持する命令はありますか? いいえの場合、なぜですか?
次の x86-32 命令を想定します。
add ebx,1
このオペコードを組み立てるには、(少なくとも) 2 つの方法があります。
81 c3 01 00 00 00
また
83 c3 01
1 つ目は 1 を 4 バイトの dword として保持し、2 つ目は 1 をバイトとして保持します。
1を2バイトとして保持する命令はありますか? いいえの場合、なぜですか?
x86 命令セットの癖に出くわしました。83
Intel は、最初のオペランドが 型Ev
で、2 番目のオペランドがオペランドと同じサイズであると解釈される即値バイトであるステムの下に命令のグループを含めましたEv
。したがって83 c3 01
、01
は 32 ビット値として解釈されます。の66 83 c3 01
場合、01 は 16 ビット値として解釈されます (宛先は 16 ビットax
レジスタです)。ステムのpush
下にコーディングされたニーモニック6A
は、その単一オペランドのサイズに関して同じように動作します。
あなたの質問に対するより広い答えはノーです。16 ビット定数が 32 ビット定数として解釈されるエンコーディングはありません。
出典:逆アセンブラを書きました。
66 81 C3 01 00 (32 ビット モードの場合は「add bx, 01」) がその例と考えられます。
必要がないため、オーバーライドを必要としない例はありません。最初の例で 4 バイトが必要な理由は、4Gb 範囲全体にまたがるためです。2 番目のものは、+/-128 (合計 256 の値) に制限されているため、1 バイトのみを使用します。オーバーライドを使用することで、最初の例を 64kb に制限できますが、実際には 2 バイトに 1 バイトではなく、2 バイトのままです。
宛先のサイズに関係なく、プログラミングで小さな整数を使用することは非常に一般的です。利点は、命令のエンコードが削減されることです。多くの命令がこれをサポートしています: IMUL、ADD、ADC、SUB、SBB、AND、CMP など。
理由については、バイトエンコーディングの節約と比較して、追加の節約は最小限であると思います。ENTER 命令は 16 ビットの即値を使用しますが、符号なしであり、更新レジスタ RSP/ESP/SP に固定されています。