6

x86 命令セットでは、オペコードのインデックス 1 のビットは、デスティネーション オペランドとソース オペランドを指定する方向ビットか、符号拡張ビットのいずれかです。

例えばadd

  • 00 /r ADD r/m8, r8vsそのビットは、同じニーモニックの vs. を区別02 /r ADD r8, r/m8
    しますr/m, regreg, r/m
  • 81 /0 id ADD r/m32, imm3283 /0 ib ADD r/m32, imm8
    フル (ビット 1 クリア) 対符号拡張即値 (ビット 1 セット)

これらのケースのどれであるかを判断する最も簡単な論理的な方法は何だろうと思っています。命令オペコードをチェックし、それらを比較してそれがどれであるかを確認する以外にチェックする方法はありますか (命令の符号拡張または方向ビット バリアントの場合)。このビットを無視する命令もありますが、0 に設定されているので問題ありません。

編集: 書き込みエラー (私のコードが意図したもの) の場合、ar/m->reg 命令は決して書き込みエラーをトリガーしないため、reg->r/m が常に当てはまることがわかります。しかし、他の誰かが同様の問題に遭遇した場合に備えて、どんな情報でもいいでしょう.

4

2 に答える 2

4

[コメントを回答にしました]。

明らかに、命令バイトのストリームに対してブール式が必要です。その式を簡単に定義する方法がわかりません。x86 には非常に厄介な命令セットがあります。重要なトリックは、プレフィックスバイトによって決定されるテーブルでオペコードバイトを検索することだと思います。なんらかの逆アセンブラを作成している場合は、そのようなテーブルがすでにあることを期待しています。

于 2011-08-03T07:26:24.970 に答える
1

方向ビットと符号ビットは、x86 プロセッサのフラグ レジスタの一部です。フラグの最下位 8 ビットは 8080/8085/Z80 のフラグと同じレイアウトであるため、インデックス 1 のビットが符号付きビットであると推測されます。私の記憶が正しければ、70 年代後半に 8086/88 プロセッサで導入されて以来、方向ビットの位置は変更されていません。

符号ビット ビットは算術演算の結果として変更され、演算結果の最上位ビットのコピーです。INC および DEC は符号ビットに影響しません。

方向ビットは、cld/std 命令を使用して操作され、ブロック命令 (cmps、ins、lods、movs、outs、scas、および stos) がポスト インクリメント/デクリメントするかどうかを制御します。

スタックを介して操作することもできます (ただし、これは符号ビットではおそらく意味がありません)。

pushf
and dword ptr [esp],SOME_MASK
popf

「and」の使用は一例です。or、xor なども使用できます。

フラグを操作した場合、一部のランタイム ライブラリはフラグが変更されていないと想定するため、フラグを以前の値に戻す必要がある場合があります。

于 2011-08-04T14:41:02.850 に答える