関数 fが,関数gから呼び出された場合の,関数fから見た双方のスタック・フレームの内容を以下に示します。
関数fが4 ワード(16バイト)より大きいパラメータ・サイズを持つ場合に,4 ワードを越えた分のパラメータを設定している領域です。パラメータ・サイズが4ワード以下であれば,この領域はサイズ0となります。
パラメータを受け取るレジスタ(r6〜r9)を設定するための領域です。16バイト固定ではなく,不要であればサイズ0となります。
パラメータ・レジスタ領域の詳細は,「(2) パラメータ・レジスタ領域」を参照してください。
関数f 内で使用する関数呼び出し前後で内容が保証されるレジスタを退避するための領域です。退避する必要があるレジスタ本数分だけ,この領域のサイズが必要となります。
レジスタの退避と復帰は,基本的にprepare/dispose命令を使用することになるので,この退避領域へはレジスタ番号昇順にストアされます。
たとえば,r28〜r31を退避する場合は,以下の並び順となります。
関数f が他の関数を呼び出す際に,4ワードより大きいサイズの引数を設定するための領域です。他の関数を呼び出す際に必要となる引数は,関数f のスタック・フレーム内に領域を確保して設定します。
呼び出しに要する引数サイズが4ワード以下の場合,この領域はサイズ0となります。
パラメータ・レジスタ領域は,パラメータ・サイズが4ワード(16バイト)を越える場合に,必要に応じて確保する領域です。パラメータ・レジスタ(r6〜r9)を必要に応じてこの領域にストアするため,この領域のサイズは0,4,8,12,16バイトのいずれかです。
この領域は,パラメータ・レジスタの内容とスタック内のパラメータとを,連続した配置関係で参照する必要がある場合に,パラメータ・レジスタをストアするためのものです。
たとえば,サイズが20バイトの構造体引数を値渡しする場合,16バイトはr6〜r9 で,残りの4バイトはスタック(5 番目のパラメータ・ワード)として渡されます。
値渡しした構造体全体を参照するためには,メモリ上に全体を連続した位置関係で配置する必要がありますが,関数呼び出し直後は,レジスタとメモリに分割された状態になっています。
この場合,呼び出される側の関数でパラメータ・レジスタをスタックへストアすることにより,値渡ししたST20をメモリ上で参照することができます。
この領域が必要となる具体的なケースは,パラメータが以下の場合です。
これらいずれかに該当しなければ,パラメータ・レジスタをパラメータ・レジスタ領域へストアする必要はないため,パラメータ・レジスタ領域は不要(サイズ0)となります。
この場合には,r7〜r9 をパラメータ・レジスタ領域へストアします。
r6 は,ST20と連続した位置のメモリ上に配置する必要がないのでストアしません。
したがって,パラメータ・レジスタ領域のサイズは12バイトとなります。
なお,構造体や共用体が,パラメータ・レジスタとスタックにまたがっていない場合は,パラメータ・レジスタ領域へのストアは不要になり,パラメータ・レジスタ領域はサイズ0バイトとなります。
この場合は,ST12はパラメータ・レジスタ内にすべて収まり,ST8はパラメータ・レジスタでは渡ってきません。
そのため,パラメータ・レジスタとスタックにはまたがらないので,パラメータ・レジスタ領域はサイズ0バイトとなります。
なお,パラメータ・レジスタで全体を受け取った構造体や共用体は,メモリ上に展開する際には,ローカル変数領域に展開されます。
可変個数の実引数を受け取る場合には,パラメータ・レジスタ領域へストアする必要があります。