一般に、逆アセンブラには、テーブルと「デコード タイプ」(通常は関数ポインタまたは switch ステートメントに入る何か)の組み合わせがあります。デコード タイプは、命令がどのクラスであるかを示します。たとえば、xor, or, and, add, sub
同じデコードしcall, jmp
ますが、別のデコードになります。jnz, jz, jnc, jc, ja, jb, jbe, etc
さらに別のデコードタイプがあります。
したがって、最初のレベルのテーブルは 256 エントリ テーブルになります。0xff
次に、次のバイトが命令が「実際に」何であるかを示す「プレフィックス」などの特定のエントリがあります。ここでも、256prefix0xff
エントリ テーブルのテーブルが得られます。
これまでのところ、すべての組み合わせが使用されているわけではないため (ほぼすべてではありますが)、一部のエントリは有効ではない可能性があります。
注意が必要なのは、「修飾子プレフィックス」エントリです。たとえば、0x66 は命令のオペランド サイズを 32 ビットから 16 ビットに切り替えます (プロセッサが 16 ビット モードの場合はその逆)。
各カテゴリ内の実際のデコードの多くには、ビットをいじり、「ビット 5 ~ 3」をレジスタ番号に、または「ビット 1 ~ 2」をアドレス モードに変換することが含まれます (たとえばeax
、 、[eax]
または)。[eax+esi]
かなり大変な作業です。私は 80186 用の逆アセンブラを書きましたが、ほぼ終日の作業で約 2 日かかりました。しかし、私は自分が何をしているのかをすでに知っていました。それを 386 に変換するには、さらに 2 ~ 3 日かかりました。SSE、MMX、3DNow をすべて備えた最新の x86 プロセッサでそれを行うことは考えたくありません。などの指示。
[そして、「正しい答え」を得るためにこれを行う方法を説明するのに非常に長い時間を費やしました-これはあなたがこれを行う方法の正しい答えですが-もちろん、既存のライブラリを使用することは明らかにより簡単な方法ですそれ]。