6

私は逆アセンブラを書いていて、命令フォーマットをレビューしていて(そして手作業でいくつかの逆アセンブルを行っていました)、デコードできないように見える命令に遭遇しました。

その特定の命令の出力(objdumpから)は次のとおりです。

c6 05 14 a0 04 08 01    movb   $0x1,0x804a014

ただし、オペコードc6はMOV Eb Ib(Mod R / Mからimm8)であると想定されているため、命令がどのようにデコードされるのかわかりません。

誰かがそれがどのようにデコードされるかについて私に教えてもらえますか?

ありがとう!

4

3 に答える 3

5

これは Alex Frunze の回答によって (部分的に) 説明されていますが、彼は少し簡潔なので、ここでいくつかの説明を提供します。

  1. オペコードは c6/0 で、命令に 2 つのオペランドがあることを示します。1 つは r/m 8 で、これは mod/rm バイトでエンコードされたオペランドと即値オペランドを意味します。両方のオペランドは 8 ビット幅です。
  2. オペコードの /0 は、オペコードの一部が mod/rm バイトにエンコードされていることを意味します。mod/rm バイトのビット 3 ~ 5 はオペコードの一部です。c6 の後にビット 3 ~ 5 の値が 0 の mod/rm バイトが続くと、mov オペコードが得られます。
  3. 値 5 (c6 の直後のバイト) は、r/m バイトの 00 000 101 (バイナリ) に対応します。
  4. r/m バイトの「最後の 3 つ」(ビット 0 ~ 2) は、r/m フィールドに対応します。r/m 値 101 (5) は「ディスプレースメント dword を使用する」ことを意味するため、mod/rm バイトに続く次の 4 バイトは即値アドレスを形成します。
  5. 14 a0 04 08 は、0x0804a014 のリトル エンディアン エンコードです。
  6. 最後のバイト 1 は、アドレスにロードする即値です。

これが役立つことを願っています。

于 2012-09-11T06:57:20.030 に答える
3

c6 - オペコード (Mod/RM バイト、/digit(reg) フィールドにもオペコードの一部があります)
05 - Mod/RM バイト (mod=00b、r/m=101b、/digit(reg)=0 - 一部オペコードの)
14 a0 04 08 - disp32
01 - imm8

そして、それはmovからIbまでEbです。おそらく、objdump が逆アセンブルを示している AT&T の構文と、Intel/AMD のドキュメントの構文を混同しているのでしょう。AT&T 構文のオペランドの順序は、x86 CPU のマニュアルとは逆です。

于 2012-09-11T06:21:17.910 に答える
3

まあ、即時に移動することは何の意味もありません。その命令が行うことは、定数 1 を 0x804a014 にあるメモリ バイトに移動することです。同等の C コードのようなもの:

*(unsigned char *)0x804a014 = 1;

c6ご存知のように、opcode があります。これは、ドキュメントの Volume 2A のMOV説明の一部として調べることができます。

05ModR/M バイトです。ボリューム 2A の表 2-2、「ModR/M バイトを使用した 32 ビット アドレッシング フォーム」を使用して解読できます。05チャートの「ModR/M バイトの値 (16 進数)」の部分を探します。そこから左にトレースすると、この ModR/M 値の実効アドレスが「disp32」形式で指定されていることがわかります。そこの脚注には、「disp32命名法は、ModR / Mバイトに続く32ビットの変位を示します」と書かれています。この場合、それは命令の次の 4 バイトです: 14 a0 04 08.

最後に、8 ビットの immediate01があり、完全な命令がデコードされます。

于 2012-09-11T06:19:55.180 に答える