Skip to main content

IAR Embedded Workbench for Arm 9.70.x

自動変数とパラメータの記憶領域

このセクションの内容:

関数内で定義された(static宣言ではない)変数は、C言語規格では自動変数と呼ばれます。これらの変数の一部はプロセッサレジスタに配置され、残りはスタック上か、に配置されます。意味上は、これらは同一です。主な違いは、変数をスタックに配置するよりもレジスタに配置した方がアクセスが高速で、必要なメモリ容量も小さくなるということです。

自動変数は、関数の実行中にのみ有効になります。関数から戻るときに、スタックに配置されたメモリは解放されます。

スタック

スタックには、以下を格納できます。

  • レジスタに格納されていないローカル変数、パラメータ

  • 式の中間結果

  • 関数のリターン値(レジスタで引き渡される場合を除く)

  • 割り込み時のプロセッサ状態

  • 関数から戻る前に復元する必要のあるプロセッサレジスタ(呼び出し先保存レジスタ)

  • スタック保護される関数が使用するカナリー。スタック保護を参照してください。

スタックは、2つのパートで構成される固定メモリブロックです。最初のパートは、現在の関数を呼び出した関数やその関数を呼び出した関数などに配置されたメモリを格納します。後のパートは、割当て可能な空きメモリを格納します。2つの領域の境界をスタックの先頭と呼び、専用プロセッサレジスタであるスタックポインタで表します。スタック上のメモリは、スタックポインタを移動することで配置します。

関数が空きメモリを含むスタックエリアのメモリを参照しないようにする必要があります。これは、割り込みが発生した場合に、呼び出し先の割り込み関数がスタック上のメモリの割当て、変更、割当て解除を行うことがあるためです。

スタックについておよびスタックメモリの設定を参照してください。

利点

スタックの主な利点は、プログラムの異なる部分にある関数が、同一のメモリ空間を使用してデータを格納できることです。ヒープとは異なり、スタックでは断片化やメモリリークが発生しません。

関数は自身を呼び出すことができます(再帰関数)。また、呼び出しごとに自身のデータをスタックに格納できます。

潜在的な問題

スタックの仕組み上、関数から戻った後も有効にすべきデータを格納することはできません。次の関数で、よくあるプログラミング上の誤りを説明します。この関数は、変数xへのポインタを返します。この変数は、関数から戻るときに無効になります。

int *MyFunction()
{
 int x;
 /* Do something here. */
 return &x; /* Incorrect */
}

別の問題として、スタック容量が不足する危険性があります。この問題は、関数が別の関数を呼び出し、その関数がさらに別の関数を呼び出す場合など、各関数のスタック使用量の合計がスタックのサイズよりも大きくなるときに発生します。大きなデータオブジェクトがスタック上に格納されたり、再帰関数が使用されると、リスクは高くなります。