2017-03-08 6 views
0

私はUEFI EDK2 Biosソースで作業しています。我々は、EDK2ソースにプラットフォーム関連の新しいパッケージを作成しました。私が追加したプラットフォームに関連するコードには、奇妙な問題があります。Cファイルのローカル変数がスタックに作成されていません.GCCコンパイルコード

ソースレベルのデバッグを行ったとき、GCCでコンパイルされたときに、C関数内のローカル変数がスタックに作成されていないことに気づきました。

ビジュアルスタジオでコンパイルしたときと同じUEFIコードを、次にC関数のローカル変数をスタックに作成しています。

私は、スタックベース、全てのセグメントレジスタ、現在のコード実行、メモリなどを見ることができるシミュレーション環境でこのコードを実行しています。..

そのマルチコアシステムが、有効で唯一のブートストラップ・プロセッサ

+4

おそらくGCCは変数をレジスタに入れたり、使用されていなかったために最適化したのでしょうか?なぜこれが問題であるのかを記述することはできません(もちろんコードを表示することもできません)。 – unwind

+1

最適化の問題でしょうか?ローカル変数(a.k.a. *自動変数*)は、*スタック上に*存在しません。 –

答えて

0

C11言語仕様を読んだ場合は、スタックまたはスタックフレームの記述やスタック上の変数の記述がないことがわかります。どのような種類のスタックにも自動変数を入れる必要はありません。

自動変数(つまり、関数スコープ内に定義されていて、staticキーワードなしで定義された変数)をプログラムがどのように格納するかは、完全にコンパイラの責任です。昔、ほとんどのコンパイラは引数、戻りアドレス、ローカル変数のためにシステムスタック上にスペースを作成していました。現代では、プロセッサは一般的に多くのレジスタを持っており、できる限りローカル変数と関数引数をレジスタに保持するほうが効率的です。コンパイラは、スタック上の自動変数を格納する必要がある理由を2つだけの理由がある

:レジスタ

  • 関数が取るでそれらすべてを置くためにあまりにも多くの変数と引数があり

    1. 変数のアドレス(レジスタへのポインタを持つことはできません)

    gccはおそらくスタックを作成する必要がないと判断していますあなたの変数のためのスペースとレジスタに入る。 Visual Studio Cコンパイラは、常にMicrosoftによって無視されていたことで有名でしたので、自動変数に関する最新のアイデアではあまり最新ではありません。

    また、コンパイラが変数を最適化することが多いことがわかります。あなたの変数に有用な何かをしないと、コンパイラはそれがまったく必要ないと判断するかもしれません。たとえば、次のコード

    int f() 
    { 
        int i; 
    
        for (i = 0 ; i < 10 ; ++i); 
        return 0; 
    } 
    

    にループが空であるため、コンパイラはそれを捨てることができ、それはあまりにもそれを捨てますので、それは変数を必要としません知っています。

  • 関連する問題