next up previous
: 参考文献 : [補足] C 言語でのメモリの利用のされ方 : メモリの 4 領域

スタックの使われ方の例

2 のプログラムを完成させた 図 6 の C 言語プログラムを考えよう。 既に解説したように、変数 b には a の 2 乗、 すなわち 25 が格納されてプログラムが終了する。
図 6: 関数 square の利用。なお、S は定義しただけで使用していない。
\begin{figure}{\tt
int square(int i); // 関数のプロトタイプ\\
int S; // グロー..
...int i)\{ // square エリソ瑤遼楝瑠\
\hspace*{1cm}return(i*i);\\
\}
}\end{figure}
この時、main 関数や square 関数の外部で定義した変数 Sグローバル変数となり、プログラム中の全ての位置で利用することができる。 一方、main 関数内の変数 a, b や square 関数の引数 i は その関数内部でしか参照できないローカル変数である。
図 7: square 関数を用いた時のメモリのスタック領域の模式図。(a) square 実行前、(b) 実行中、(c) 実行後。
\begin{figure*}\begin{center}
\epsfbox{stack.eps}\end{center}\end{figure*}
前節でふれた様に、グローバル変数 S はメモリの静的領域に確保され、 変数 a, b, i はメモリのスタック領域に確保される。 グローバル変数 S の取り扱いは本演習で今まで何度も取り扱って来たので 解説は割愛し、 ここでは変数 a, b, i のメモリ上での配置について概説しよう。 図 7 に square 関数を用いた時のメモリのスタック領域の模式図を示した。

まず square 関数が実行される前には、 main 関数で定義された変数 a, b はスタック領域に図 7(a) のように確保される。 スタックポインタ $sp は演習で取扱ったように使用されているスタック領域の low address 側の境界を指し示している。 このとき、教科書図 3.12 のようにフレームポインタ $fp はスタック領域の high address 側の境界を表す [2]。 なお、図は教科書と本資料で上下が逆転していることに注意しよう。

square 関数が実行されている最中のスタック領域の模式図は 図 7(b) である。本演習で扱ったように、 リターンアドレス $ra が保存されるとともに、$fp などの他の レジスタも保存される。さらに square の引数である a の値、 すなわち 5 も確保されていることがわかる。 この 5 の 2 乗が CPU で計算されて戻り値を表すレジスタ $v0 に 格納される。

square 関数が終了するとスタック領域は図 7(c) のようになり、 戻り値 $v0 の値が変数 b に代入されてプログラムが終了する。

なお、第 3 章で記述してもらった関数 square は図 7 をそのままアセンブリ言語化しているわけではなく、 その簡略版になっていることに注意しておく。

以上のように C 言語のプログラムを書く際、使用されるメモリの状態を 想像できるようになれば、C 言語の初心者のレベルを卒業したと言えるのでは ないだろうか[3]。


平成16年11月17日