2011-12-23 7 views
1

以下に示すコードの場合、住所を印刷すると次のようになります。プログラムはここでどのようにスタックを使用していますか?

&test_var1 = 0x7fff0067d87c 
&barrier (passed argument) = 0x7fff0067d770 
&i (passed argument) = 0x7fff0067d77c 
&test_var2 = 0x7fff0067d78c 

私がここで理解していない2つのことがあります。まず、Cが右から左に引数をプッシュし、次に& i&のバリアよりも大きいことを読んでいます。スタックが上位アドレスから下位アドレスに増加することを知り、& iは、より低いアドレスにあるはずです。さらに、ローカル変数test_var2はさらに大きなアドレスにあります。

第二に、人は一緒に近いことが&バリア& test_var1の値を期待するだろうが、いいえ、あなたは、268バイトの大きな違いを参照してください。その間にあるスタックは何ですか?

私は最適化O3を使用していることに注意してください。これが原因ですか?多分コンパイラがここでいくつかのトリックを果たしたでしょうか?私はvolatileを使用して、すべての変数がここにスタックにあり、いくつかのレジスタにキャッシュされていないことを確認します。

void some_func() 
{ 
......... 
{ 
    volatile int test_var1 = 0; 
} 
call_func(i, &barrier); 
........ 
} 

void call_func(volatile int i, volatile pthread_barrier* barrier) 
{ 
volatile int test_var2 = 0; 
........ 
} 
+1

スタックの使用方法は、特定のCコンパイラで実装されています。あなたはあなたのケースでGCCソースでこれを見ることができます。 –

+0

コンパイルして実行できる完全な例を含めると、私たちにとってもっと簡単になります。 – NPE

+0

'volatile'は変数の*アドレス*に影響しません。 'volatile int'はint自体が変更可能であることを意味しますが、' volatile whatever * 'は 'volatile'であることを意味しますが、ポインタ(すなわち変数)自体はvolatileではありません - もう一方の方法は 'whatever volatile * 'です。 – ams

答えて

3

x86では、f()がg()を呼び出すときに使用されるスタックは、下に向かって大きくなります。

どのようにしても、コンパイラが特定の呼び出しに対してvar/sを整理する方法は実装依存です。

+0

上位アドレスから下位アドレスに向かって大きくなります。より高い住所から低い住所に行く私のために、それはあなたのために下方に向かって上方に呼び出されます。しかし、私はそれを言うと思っていました。そう、あなたは正しいのです。私は上向きまたは下向きに言わずに、高い方から低い方へと質問するように編集しました。 – MetallicPriest

1

あなたが本当に保証されているいずれも、ここでの仮定の束を作っている:

  • コンパイラは関数を呼び出すときのレジスタのいくつかの数をプッシュする必要があります。引数とローカル変数の間にあることができないというルールはありません。
  • 引数が特定の順序でスタックに入れられなければならないというルールやスタック上にあるイベントはまったくありません。引数もレジスタに渡すことができます。
  • メモリがプログラムスタックにどのように編成されるかは、プロセッサによって異なります。 x86アーキテクチャでは、が下向きになります。、上向きではありません。
+1

"x86アーキテクチャーでは、成長が遅くなります"。これは確かに真実ではありません。なぜなら、逆アセンブリの関数を見ると、関数の始めにrspが減算され、最後に追加されることになります。そして、実際には、すべてがスタック上にあることを確認するためにvolatileを使用していました。私の質問でそれを修正しました。 – MetallicPriest

+0

Googlingからの最初のリンク 'x86 stack architecture'はそうでないと言う:http://wiki.osdev.org/Stack#Stack_example_on_the_X86_architecture –

+0

それを解釈する方法。上向きには私はより高い住所からより低い住所へと意味し、あなたとこのリンクはそれを下方に呼んでいます。基本的に言いたいのは、上位アドレスから下位アドレスに向かって成長するということです。 – MetallicPriest

関連する問題