コールスタックの機能
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/03/30 08:24 UTC 版)
「コールスタック」の記事における「コールスタックの機能」の解説
前述のように、コールスタックの第一の目的は以下の通りである。 リターンアドレスの格納 サブルーチンが呼び出されたとき、戻るべき命令のアドレスをどこかに記憶しておく必要がある。スタックを使ったリターンアドレスの格納は他の方法にはない利点がある。第一に、各タスクは対応するスタックを持っているので、サブルーチンは再入可能(リエントラント)、つまり複数のタスクが同時に同じサブルーチンを実行することが可能となる。第二に、再帰呼び出しが可能となるという利点がある。関数自身は再帰的に呼び出されたとしても、リターンアドレスは呼び出される度に記憶しておかなければならない。スタックを使うとこの機能が自動的にサポートされる。 言語、オペレーティングシステム、ハードウェア環境に依存するが、コールスタックはそれ以外の機能も持つことがある。そのような機能として以下のものがある。 局所データ格納域 多くのサブルーチンは局所変数(自動変数)の値を格納するメモリ領域を必要とする。局所変数とは実行中のサブルーチンでのみ使われる変数で、そのサブルーチンの処理が終われば値を必要としない。このためにスタックのトップを動かして空き領域を作り、局所変数に利用することができる。これは動的メモリ確保に比べると非常に高速に行える。サブルーチンが呼び出される度にスタック上の局所データの領域が確保される点に注意されたい。 引数受け渡し サブルーチンには引数を必要とするものがある。引数は呼び出し側のコードが提供し、その引数をコールスタック上に置くことは珍しくない。一般に引数の個数が少なければ、プロセッサのレジスタが引数の受け渡しに使われる。しかし、引数の個数が利用可能なレジスタ数より多ければ、何らかのメモリ領域を使わざるを得ない。コールスタックはそのような値の受け渡しには最適で、サブルーチンの呼び出しの度に固有の引数が渡されるのに対して、コールスタックも呼び出しの度に固有の領域を与えられる。 評価スタック 論理演算や数値演算のオペランドは多くの場合レジスタに置かれて処理される。しかし、式が複雑になるとレジスタだけでは収まりきらなくなり、何らかのメモリ領域が必要となる。そのようなオペランドのためのスタック(逆ポーランド記法の電卓に似ている)は評価スタック (evaluation stack)と呼ばれ、コールスタックを利用して実装することがある。 現在のインスタンスへのポインタ C++のようなオブジェクト指向言語では、メソッド呼び出しの際にthisポインタを引数と共にコールスタックに格納する。thisポインタは呼び出されるメソッドに対応するオブジェクトのインスタンスを指している。thisポインタはオブジェクト指向言語のコンテキストの基本要素であり、現在のオブジェクトの持つプライベートデータへのアクセスを提供する。thisポインタはオブジェクト指向プログラミングとコールスタックを結びつけるものである。 ルーチンの入れ子における静的スコープサポート PascalやAdaといったプログラミング言語はサブルーチンの入れ子が可能であり、内側のルーチンが外側のルーチンのコンテキスト(外側のルーチンの引数や局所変数)にアクセスできるようになっている。この静的な入れ子はいくつも繰り返すことができ、関数の中に別の関数を定義し、その中でさらに別の関数を定義し……といったことが可能である。このため実装に当たっては呼び出された関数が静的な入れ子を遡って外側のフレームにアクセスできる手段を提供する必要がある。一般に外側のフレームへのポインタとしてこの参照を実装し、これを「ダウンスタック・リンク」または「スタティック・リンク」と呼んで、直前の呼び出し側ルーチンとのリンク(ダイナミック・リンク)と区別する(呼び出し側は定義上の外側のルーチンとは限らない)。例えば、内側のルーチンは自分自身を再帰呼び出しできるようになっている言語が多く、同じルーチンのスタックフレームがコールスタック上にいくつも重なることがあり、それらが全て同じ外側のルーチンのコンテキストへのスタティック・リンクを持つことになる。スタティック・リンクの代わりに、外側のスタックフレームへの参照を集めてポインタの配列とする方式もある。この配列を display と呼び、インデックスを指定することで必要なフレームを得ることができる。バロース B5000 はハードウェアでこれをサポートしており、32レベルの静的入れ子を使用可能だった。 他のリターンステータス リターンアドレスだけでなく、環境によってはサブルーチンから復帰する際に戻さなければならないハードウェアやソフトウェアのステータスがあるかもしれない。例えば、特権レベル、例外処理情報、演算モードなどである。必要に応じてこれらもリターンアドレスのようにコールスタックに格納される。 典型的なコールスタックはリターンアドレス、局所データ、引数を格納する(これを「コールフレーム」と呼ぶ)。環境によってはコールスタックの機能に差異がある。例えばFORTH言語では、コールスタックにはリターンアドレスと局所変数のみが格納され(これをリターンスタックと呼ぶ)、引数は別のデータスタックに格納される。多くのFORTHの実装では浮動小数点数の引数を格納するための第三のスタックが存在する。
※この「コールスタックの機能」の解説は、「コールスタック」の解説の一部です。
「コールスタックの機能」を含む「コールスタック」の記事については、「コールスタック」の概要を参照ください。
- コールスタックの機能のページへのリンク