|
関数の stack frame の構成と変数へのアクセス
本コンパイラーで生成する関数オブジェクトの、スタックの構成やローカル変数へのアクセスについて、次に図をもちいて示します.
(1)stack frame の基本構成
sp ---> |
local 3
 |
local2[0] |
local2[1] |
local2[2] |
local 1 |
[bc] frame pointer |
return address |
arg1 |
arg2 [ 00 ] |
|
bc ---> |
|
func(arg1,arg2)
int arg1;
char arg2;
{ int local1;
char local2[3];
....................
....................
{ int local3;
..............
..............
}
....................
}
|
func: | push | bc | ; 関数入口処理 |
| ld add ld ld ld add ld | hl,0 hl,sp b,h c,l hl,(@10xx) hl,sp sp,hl |
| ........................ |
| ........................ |
| ........................ |
| ld | h,b | ; 関数出口処理 |
| ld ld pop ret | l,c sp,hl bc |
@10xx: | defb | -7 | ; ローカル変数の総バイト数 (負符号付) |
|
関数の入口処理では、その関数で使用するローカル変数の領域をスタックに確保します.そして、出口処理では、確保した領域を開放してからその関数を呼び出した関数ヘリターンします.関数内のブロックの先頭で宣言される変数の領域についても、当該ブロックの処理の実行の如何を問わず、人口処理でまとめて確保します.
呼び出し側関数の bc レジスタは、入口処理の先頭でスタックに退避し、その退避したアドレスを bc レジスタに格納します.これにより、ローカル変数は、bc レジスタのアドレスからのオフセットを用いることによりアクセスすることができます.このため、bc レジスタは、フレームポインタとして常に実行中の関数のスタックフレームを管理していることになります.
|