を含む、命令の即時バージョンの多くのオペコードは、ModR/Mバイト83
の3ビット/r
フィールドを3つの追加のオペコードビットとして使用します。Intelのvol.2マニュアルにはこれが記載されており、付録のオペコード表に含まれていると思います。
これが、 dst / srcオペランド、およびイミディエートオペランドを意味するオペコードのエンコードに両方のModRMフィールドが使用される場合とは異なり、または両方のModRMフィールドが使用される場合とは異なり、ほとんどのオリジナルの8086イミディエート命令がand r/m, imm
まだ2つのオペランドのみを許可する理由です。shrd eax, edx, 4
imul edx, [rdi], 12345
SHRD / SHLDは386で追加され、imul-immediateは186で追加されました。copy-and-AND(and eax, edx, 0xf
)がエンコードできないのは残念なことかもしれませんが、少なくともx86は非常に一般的なコピーと追加にLEAを使用できます。サブ操作。
しかし、すべての即時および1オペランドの命令(push
またはなどnot
)がそれ自体に対して完全なオペコードを必要とする場合、8086は1バイトのオペコードを使い果たしてしまいます。(特に、設計者がALとAXのmodrmバイトのない短い形式に多くのコーディングスペースを費やすことを選択したためです。たとえばcmp ax, 12345
、16ビットモードでは4バイトではなく3バイトであるか、32cmp eax, imm32
では6バイトではなく5バイトであるなどです。 cmp r/m32, imm32
-ビットモード。シングルバイトのxchg-with-ax、および1バイトのinc / decレジスタの場合。)
例:デコード48 83 C4 38
。 (「レジスタ/オペコード」フィールドに応じて、1つのオペコードバイトをどのように異なる命令にデコードしますか?それは何ですか?、このQの複製から)
48
はREX.Wプレフィックスです(Wビットのみが設定されているREXであるため、64ビットのオペランドサイズを示しますが、上位レジスタはありません)。
オペコード83
は、「レジスタ/オペコードフィールド」と呼ばれるフィールドに応じて、7つの異なる命令になる可能性があると述べています
各命令の独自のドキュメント、たとえばadd
(vol2マニュアルのhtml抽出)
REX.W + 83 /0 ib
には、のようなエンコーディングが示されADD r/m64, imm8
ています。これは、あなたが持っているものです。
wiki.osdev.orgのModRMビットフィールドの図
7 0
+---+---+---+---+---+---+---+---+
| mod | reg | rm |
+---+---+---+---+---+---+---+---+
0xc4 = 0b11000100であるため、regフィールド= 0です。したがって83 /0
、Intelの表記では、オペコードはです。
残りのModRMフィールドは次のとおりです。
だから指示はadd rsp, 0x38
ndisasm -b64
同意する:
$ cat > foo.asm
db 0x48, 0x83, 0xC4, 0x38
$ nasm foo.asm # create a flat binary with those bytes, not an object file
$ ndisasm -b64 foo
00000000 4883C438 add rsp,byte +0x38