残念ながら、x86 エンコーディングは複雑で不規則であり、それを理解するのは大変な作業です。エンコーディングの最良の「クイック スタート」は、sandpile.org の一連の HTML ページです (簡潔ですが、かなり詳細です)。
最初: http://sandpile.org/x86/opc_enc.htm - 「命令エンコーディング」テーブルには、命令がコーディングされている数十の方法が示されています。各行の白いセルは、命令の必須バイトを表します。次の灰色のセルは、オペコードの前に現れるさまざまなフィールドに基づいて存在します (または存在しません)。最初の行と同様に、白い「0Fh」で始まる行を確認する必要があります。同じページの下部には、さまざまな「拡張」オペコード フィールドに表示されるビットフィールドがあります。「modrm/sib」行 (最初の行) 以外はすべて無視しています。
最初の行 (1 バイトのオペコード) を除くすべての行で、"mod r/m" バイトがオペコードの後に続く必要があることに注意してください (1 バイトのオペコードの場合、命令によって異なります)。これは、ほとんどの 2 引数命令の引数をエンコードします。http://sandpile.org/x86/opc_rm.htmの表には意味があります。引数の 1 つはレジスタでなければならず、もう 1 つの引数はレジスタまたはメモリ インダイレクションです (「reg」フィールドはレジスタをエンコードし、 「mod」および「r/m」フィールドは他の引数をエンコードします)。通常、オペコードの他の場所には、引数の順序を示す「方向」ビットもあります。オペコードは、AL、AX、EAX、RAX (つまり、異なるサイズ)、または拡張レジスタの 1 つなどを操作しているかどうかも示します。
modrm では、「mod」ビットが「11」の場合、「r/m」フィールドもレジスタを参照します。それ以外の場合は、通常、名前付きレジスタを modrm バイトの後に表示される (オプションの) ディスプレースメントに追加することによって構築されたメモリ アドレスを参照します (この定数は、「mod」ビットに応じて 0、1、または 4 バイトの長さになります)。例外は、"r/m" ビットが "100" (つまり 0x4) の場合で、通常は "SP" と呼ばれます。この場合、メモリ引数は、modrm バイトの直後に続く追加の "sib" バイトによって記述されます。 (すべての modrm 変位は sib の後に表示されます)。SIB のエンコーディングについては、http://sandpile.org/x86/opc_sib.htmを参照するか、modrm ページからクリックしてください。
最後に、方向とサイズがどこから来たのかを理解するために、いくつかのオペコードを見てください: http://sandpile.org/x86/opc_1.htm . 最初の 4 つのエントリはすべて「ADD」で、引数は 2 つの異なる順序であり、2 つの異なる幅です。したがって、この場合、命令の下位ビットは方向と幅をエンコードしています。