7

この C プログラムから取得した非常に単純な SPARC アセンブリ出力を見てみました。

int addition_func(int a, int b)
{
  return(a+b);
}

void main()
{

int a = 20;
int b = 19;
int res;    

res = addition_func(a, b);
}

セクション .text の分解:

00000000 <addition_func>:
 0: 81 c3 e0 08     retl 
 4: 90 02 00 09     add  %o0, %o1, %o0

00000008 <main>:
 8: 90 10 20 14     mov  0x14, %o0
 c: 92 10 20 13     mov  0x13, %o1
10: 82 13 c0 00     mov  %o7, %g1
14: 40 00 00 00     call  14 <main+0xc>
18: 9e 10 40 00     mov  %g1, %o7
1c: 01 00 00 00     nop 

「call」命令が次のように言う理由がわかりません。

  call  14 <main+0xc>

そうでない理由:

  call  0 <addition_func+0x0>

プログラムは正常に動作しますが、この出力はあまり意味がありません。なぜこのように処理されるのか、何か提案はありますか?

ありがとう

4

2 に答える 2

8

GCC を使用していると仮定しますが、他のコンパイラ/アセンブラにも同等のオプションが必要です。

これはアセンブリの出力ではありません。それは分解です。アセンブラへの入力が必要な場合は、 を使用しますgcc -S

注目すべき数字は 14 ではありません — 命令は相対アドレス0への呼び出しです。

14: 40 00 00 00     call  14 <main+0xc>

でコンパイルされたオブジェクト ファイルを逆アセンブルする場合-ffunction-sections、命令はリンカによって修正される単なるプレースホルダです。リンカは への実際のオフセットを入力しaddition_funcます。再配置テーブルをダンプすると、これが表示される場合があります。

于 2010-07-21T15:11:36.683 に答える
2

簡単に言うと、これは、実際のシンボルへのリンカーによって適切なオフセットが埋められるのを待っている、オブジェクト ファイル内の埋められていない相対呼び出しです。それまでは、相対オフセットは x86 のように 0 です。これは、相対的に自分自身を呼び出していることを意味します(これはたまたまコード セグメント内の絶対アドレス 0x14 であり、メインからの 0xc のオフセットです)。SPARC 相対呼び出しは、x86 のように終了ではなく、現在の命令の開始に対して相対的であるように見えます。

于 2021-02-26T03:23:19.077 に答える