2012-02-24 4 views
6

後はオペランドのx86-64上のCALL命令の世代AMD

080483b4 <display>: 
80483b4:  55      push %ebp 
80483b5:  89 e5     mov %esp,%ebp 
80483b7:  83 ec 18    sub $0x18,%esp 
80483ba:  8b 45 0c    mov 0xc(%ebp),%eax 
80483bd:  89 44 24 04    mov %eax,0x4(%esp) 
80483c1:  8d 45 fe    lea 0xfffffffe(%ebp),%eax 
80483c4:  89 04 24    mov %eax,(%esp) 
80483c7:  e8 ec fe ff ff   call 80482b8 <[email protected]> 
80483cc:  8b 45 08    mov 0x8(%ebp),%eax 
80483cf:  89 44 24 04    mov %eax,0x4(%esp) 
80483d3:  c7 04 24 f0 84 04 08 movl $0x80484f0,(%esp) 
80483da:  e8 e9 fe ff ff   call 80482c8 <[email protected]> 
80483df:  c9      leave 
80483e0:  c3      ret 

080483e1 <main>: 
80483e1:  8d 4c 24 04    lea 0x4(%esp),%ecx 
80483e5:  83 e4 f0    and $0xfffffff0,%esp 
80483e8:  ff 71 fc    pushl 0xfffffffc(%ecx) 
80483eb:  55      push %ebp 
80483ec:  89 e5     mov %esp,%ebp 
80483ee:  51      push %ecx 
80483ef:  83 ec 24    sub $0x24,%esp 
80483f2:  c7 44 24 04 f3 84 04 movl $0x80484f3,0x4(%esp) 
80483f9:  08 
80483fa:  c7 04 24 0a 00 00 00 movl $0xa,(%esp) 
8048401:  e8 ae ff ff ff   call 80483b4 <display> 
8048406:  b8 00 00 00 00   mov $0x0,%eax 
804840b:  83 c4 24    add $0x24,%esp 
804840e:  59      pop %ecx 
804840f:  5d      pop %ebp 
8048410:  8d 61 fc    lea 0xfffffffc(%ecx),%esp 

、サンプルプログラムのobjdumpのの出力である私が理解する必要がどのような、メインで私たちはアドレスで次のように表示されている - 8048401、コール80483b4の場合、マシンコードは-e8 ae ff ff ffです。私はCALL命令がE8であることを知っていますが、ファンクション80483b4のアドレスはFFFFFFAEにデコードされていますか?私はGoogleで多くの検索をしましたが、何も返されませんでした。誰でも説明できますか?

答えて

8

E8は、 "Call Relative"のオペランドで、次の命令のアドレスにオペランドを加算してデスティネーションアドレスを計算します。オペランドは0xFFFFFFAEで、負の0x52です。 0x808406 - 0x52は0x80483b4です。

ほとんどのディスアセンブラは、オペランドの相対アドレスを与えるのではなく、実際のターゲットアドレスを計算するのに役立ちます。

でのx86 ISAのための完全な情報:呼び出しの近くhttp://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-manual.html

6

興味深い質問。私はIntel's documentationを見て、E8オペコードはCALL rel16/32です。 0xffffffaeは実際には-82小数に等しい32ビットの2の補数符号付き整数です。オペコードとオペランドの直後のバイトからの相対アドレスです。

あなたが数学を行う場合、あなたはそれをチェックアウト見ることができます:

0x8048406 - 82 = 0x80483b4

これはdisplay関数の先頭に命令ポインタを置きます。

+0

ご意見ありがとうございます。これはNEAR呼び出しの場合のみです。 FARの呼び出しはどうですか?あなたのコメントから、私はNEARコールがE8であることを理解しています。 FARはE8も呼びますか?また、FARコールのオペランドはabosolute addresになりますか? –

+0

@SamirBaid遠方の呼び出しは '9a'で絶対アドレスを取る。また、間接的な絶対アドレスで何かを行う 'ff'もありますが、どういうことが起こっているのか分かりません。詳細については、リンクしたページの結合ボリュームセット(上のリンクセット)のページ716を参照してください。 – spencercw

+0

@SamirBaid:遠方の呼び出しは、x86_64でもまれです。ライブラリ呼び出しは通常PLTで行われるため、2 GiByte以上のテキストセグメントが必要です。 – hirschhornsalz

3

は通常、IP-相対的である - 意味は、「アドレス」は、実際に命令ポインタからのオフセットです。そのような場合、EIPは次の命令を指します(その値は8048406です)。 ffffffae(または2の補数で-00000052)を追加すると、80483b4が得られます。

この計算はすべて32ビットであることに注意してください。ここでは64ビット操作をしていません(または、レジスタの名前にEの代わりにRがあり、アドレスはもっと長くなります)。

関連する問題