2012-03-29 10 views
4

私は非常に基本的な質問があります。その後、FOO()が呼び出されます、プロセス実行スタックでC実行スタック - ローカル変数割り当て

#include <stdio.h> 

void foo(void) { 
    char *s = "StackOverflow"; 
    printf("%s\n", s); 
} 

int main(void) { 
    foo(); 
} 

、メインがスタックにロードされます: はこのスニペットを取ることができます。 "StackOverflow"のメモリはどこに割り当てられていますか? printfが呼び出されたときに、 "%s \ n"のメモリがどこに割り当てられますか?今、私が持っている他の質問は、以下のコードを検討している


は、次のコードを考えてみましょう

#include <stdio.h> 

int x; 
int abc = 100; 

void foo(void) { 
    char *s = "stackoverflow"; 
    printf("%s\n", s); 
} 

int main(void) { 
    foo(); 
} 

をので、私はobjdumpは-s -jは.bssに行う場合。アウト、私は初期化されていないセグメントが表示され、objdump -s -j .data a.outを行う場合、私は初期化されたセグメント(abc = 100)rtを参照する必要がありますか?この前提に間違いはありますか?

でも、私は次の出力を得る:

テスト> objdumpの-s -j .bssのa.outの のa.out:ファイル形式ELF32-i386の

テスト> objdumpの-s -j .dataセクションa.outの

のa.out:ファイル形式ELF32-i386のセクション.dataセクションの

内容: 804954c 00000000 3c960408 00000000 64000000 .... < ....... D ...

私はここで何が欠けていますか?

おかげで、誰も再び

答えて

6

"StackOverflow""%s\n"文字列リテラルは、(データのみを読み込む).rodataにほとんどのシステム内のセクションを入れています。 gccを置き換えることにより、printf("%s\n",str)への呼び出しを最適化して

コメントで @FatalErrorによって追加したよう
$ gcc tst.c 
$ objdump -s -j .rodata a.out 

"%s\n"は一例でobjdumpはと表示されていない:

UNIXでは、あなたはobjdumpはコマンドを使用して.rodataセクションをダンプすることができますそれはputs(str)への呼び出しによってそれです。

objdump出力に"%s\n"文字列リテラルを表示するには、gcc -fno-builtinを使用してプログラムをコンパイルできます。

+2

Linux(と同様の)システムでは、バイナリ上で '-j -drootata'を' objdump'して見ることができます。また、 'gcc'を使うと' gcc'が 'puts()'の呼び出しにそのパターンを最適化するので、あなたは "%s \ n"を見つけられません。 – FatalError

+0

@FatalErrorあなたのコメントと同じ時間にobjdumpコマンドを書きました:) 'puts'の良い点私はそれを追加する答えを編集します。 – ouah

4

"StackOverflow"の格納場所は、標準では定義されていません。

多くの場合、プログラムの読み取り専用テキスト部分に格納されます。場合によっては、プログラムの初期化されたデータ部分に格納されることがあります。どちらもスタックではありません。これらのどちらも、「ヒープ」(malloc()らによって管理される動的に割り当てられたメモリの意味で)ではありません。同じコメントと問題がフォーマット文字列に発生します。

+0

偉大な答えをみんなに感謝!心から感謝する! – user999755

+0

@ ouahと@FatalErrorが示唆しているように、私はobjdump -s -j .rodata a.outを実行することで "Stackoverflow"と "%s"を見ることができました。 – user999755

関連する問題