アセンブラを書き直しています。それと同時に、逆アセンブリの実装にも興味があります。シンプルでコンパクトにしたいのですが、そうしている間に活用できるコンセプトがあります。
オペコードから残りの x86 命令エンコーディングを判別することができます (プレフィックス バイトも少し必要になる場合があります)。多くの人がそれを行うための表を書いていることを私は知っています。
ニーモニックではなく、命令のエンコードには興味があります。実際に難しい問題だからです。私が知る必要がある各オペコード番号について:
- この命令には modrm が含まれていますか?
- この命令には即値フィールドがいくつありますか?
- 即時に使用するエンコーディングは何ですか?
- フィールド内の即値は命令ポインタ - 相対アドレスですか?
- modrm はオペランドとレジスタ フィールドにどのような種類のレジスタを使用しますか?
sandpile.org には、私が必要とするものはいくらかありますが、解析が容易ではない形式になっています。
これらのテーブルを自分で作成して検証する前に、この質問を書くことにしました。この種のテーブルがどこかに存在することを知っていますか? 解析にあまり労力を必要としない形式で。
b byte
w word
v word or dword (or qword), depends on operand size attribute (0x66)
z word or dword (or dword), depends on operand size attribute
J instruction-relative address (next character describes type)
G instruction group, has modrm-field (next character describes operand type)
R has modrm-field (next two characters describe register and operand type)
M modrm, but operand field must point to memory
O direct offset (next character describes type)
F FPU
T separate table
_ defined, but no arguments
x 0 1 2 3 4 5 6 7 8 9 A B C D E F
0 Rbb Rvv Rbb Rvv b z Rbb Rvv Rbb Rvv b z T
1 Rbb Rvv Rbb Rvv b z Rbb Rvv Rbb Rvv b z
2 Rbb Rvv Rbb Rvv b z Rbb Rvv Rbb Rvv b z
3 Rbb Rvv Rbb Rvv b z Rbb Rvv Rbb Rvv b z
4 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
5 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
6 _ _ Mvv z Rvvz b Rvvb
7 Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb Jb
8 Gbb Gvz Gbb Gvb Rbb Rvv Rbb Rvv Rbb Rvv Rbb Rvv Mvv
9 _ _ _ _ _ _ _ _ _ _ _ _
A Ob Ov Ob Ov _ _ _ _ b z _ _ _ _ _ _
B b b b b b b b b v v v v v v v v
C Gbb Gvb w _ _ b _ _
D Gb Gv Gb Gv F F F F F F F F
E Jz Jz Jb
F _ _ Gb Gv _ _ _ _ _ _ Gb Gv
ここに、最初のオペランドのテーブルがあります。この形式は、テーブルを含むテキスト ファイルからテーブルを直接解析できるようなものです。一部の CISC およびセグメンテーション関連の指示は省略しました。
2 バイト命令の場合、そのようなテーブルが 4 つ必要になる可能性があります。3 バイト命令の場合、さらに 2 つのテーブルが必要になります。FPU 命令には 8 つのテーブルが必要ですが、これは幸いにも非常に単純です。その後、x86命令のかなり大きな部分が隠蔽されます。テーブルが 1 つまたは 2 つあれば問題ありませんが。
さらに、いくつかの命令グループでは、命令タイプを認識するためにいくつかの小さな配列が必要になる場合があります。