2

私はこの指示を見ます:

*0x804a1a0(,%eax,4)

0x804a1a0の値を取得し、$ eax * 4の値を追加しましたが、コードがジャンプした場所ではありません。値0x804a1a0自体と$eax* 4を使用して同じことを行いましたが、それは他の場所を指しています。上記の指示をどのように解釈しますか?

4

1 に答える 1

4

短い答え:

あなたは言う:

0x804a1a0の値を取得し、$ eax*4の値を追加しました

これは間違っています。

値0x804a1a0自体と$eax*4を使用して同じことを行いました

これも間違っています。

必要なのは、0x804a1a0 + eax*4最初に計算してから、そのメモリ位置の値を確認することです。

長い答え:

提供したコードは完全な命令ではなく、AT&T構文の移動/ジャンプ/呼び出し命令のオペランドです。具体的には、実効アドレスと呼ばれます。基本的に、これは間接アドレス指定の形式です。つまり、オペランドで指定された場所のメモリが使用されます。

実効アドレスのAT&T構文は次のとおりです。

DISP(BASE,INDEX,SCALE)

これは次のように解釈する必要があります。

BASE + INDEX*SCALE + DISP

あなたの場合、

0x804a1a0(,%eax,4)

本当に:

%eax*4 + 0x804a1a0

さて、http* ://wiki.osdev.org/Opcode_syntaxによると:

相対アドレス指定:すべてのジャンプおよび呼び出し命令でデフォルトで使用されます。

絶対アドレス指定を使用するには、オペランドの前にアスタリスク(*)を付ける必要があります。

また、 http: //en.wikipedia.org/wiki/Addressing_modeから:

絶対命令アドレスの実効アドレスは、変更なしのアドレスパラメータ自体です。

したがって、最終的なアドレスは、実際には。が指す場所eax*4 + 0x804a1a0です。

推測しなければならないのであれば、おそらくオフセットのジャンプ/スイッチテーブルだと思います0x804a1a0。つまり、コードはオフセットeax*4 + 0x804a1a0で実行されず、その場所に格納されているアドレスを読み取り、そこにジャンプします(したがって、間接ジャンプです)。

サイドラント:私はAT&T構文が本当に嫌いです。アセンブリを初めて使用する場合は、Intel構文を使用することをお勧めします。はるかに読みやすいと思います。Intel構文のコードはおそらく次のようになります。

jmp dword ptr [0x804a1a0 + eax*4]

命令がジャンプであると仮定します。

于 2012-10-08T19:43:12.733 に答える