9.1.2 引数と戻り値の設定方法,および参照方法

(1)

引数の受け渡し方法

引数には,レジスタで渡すものとスタックで渡すものがあります。各引数をどちらで渡すのかは,以下の手順を実施することにより決定されます。

(a)

各引数をスタック上に割り付けたメモリ・イメージを作成する

<1>

2バイト以下のスカラ型は,4バイトに整数拡張して格納されます。

<2>

各引数は,基本的にはすべて4バイト境界へと配置されます。

<3>

戻り値が構造体や共用体の場合,メモリ・イメージの先頭に,戻り値データを書き込むアドレスを設定されます。

<4>

関数原型が不明な場合には,各スカラ型の引数は以下のように格納されます。

-

1バイトのスカラ型整数 → 4バイトに整数拡張して格納

-

2バイトのスカラ型整数 → 4バイトに整数拡張して格納

-

4バイトのスカラ型整数 → そのまま格納

-

8バイトのスカラ型整数 → そのまま格納

-

4バイトのスカラ型浮動小数点数 → 8バイトの浮動小数点数に拡張して格納

-

8バイトのスカラ型浮動小数点数 → そのまま格納

例 1.

関数原型: f(ST1, ST2, ST16)
STx は,サイズがx[byte]の構造体であることを表している場合の例

 

サイズが4 の倍数でない構造体や共用体の場合,引数同士の間にパディング(図のグレー部分)ができ,この部分は内容が不定となります。

例 2.

関数原型: f(char, long, ...)
可変個数の実引数を受け取る場合の例

 

例の「これ以降は可変個数分の領域」では,実引数で設定する個数分だけメモリを消費します。

例 3.

関数原型: ST4 f(char, char, char, char)

 

rtnで,ST4 の戻り値を書き込む場所のアドレスを渡します。

(b)

作成したメモリ・イメージの先頭4 ワード(16バイト)をレジスタr6〜r9 で,4 ワードに収まらない分をスタックで渡す

<1>

レジスタ渡しの場合,各レジスタ(r6〜r9)へは各々ワード単位にロードされます。
バイト単位やハーフワード単位のロードはされません。

<2>

スタックで渡す引数は,呼び出し側関数のスタック・フレーム内に設定されます。

<3>

スタックで渡す引数をスタックへ設定する場合は,メモリ・イメージの右側から左側にかけてという順番でスタックへ格納されます。そのため,メモリ・イメージの16バイト・ オフセット位置のワードデータが,最も0に近い位置へ配置されます。

備考

スタックへの配置の方法は,「9.1.4 スタック・フレーム」を参照してください。

例 1.

関数原型: f(ST1, ST2, ST16)
STx は,サイズがx[byte]の構造体であることを表している場合の例

 

構造体(ここでは“ST16”)が一部分しかレジスタに設定できなくても,かまわずレジスタで渡します。

 

例 2.

関数原型: f(char, long, ...)
可変個数の実引数を受け取る場合の例

 

可変個数であっても,レジスタが使用できる場合はレジスタで受け渡しします。

 

例 3.

関数原型: ST4 f(char, char, char, char)

 

char型の引数4個を渡すだけでも,戻り値によっては,4番目の引数がスタック渡しとなる場合があります。

(2)

戻り値の受け渡し方法

戻り値の受け渡しの方法には,次の3通りがあります。

(a)

4バイト以下のスカラ型の場合

r10で戻り値を呼び出し側へ返却します。

4バイト未満のサイズのスカラ型の場合,4バイトに拡張したデータをr10へと設定します。

戻り値の型が, 符号なしであればゼロ拡張, 符号有りであれば符号拡張します。

(b)

8バイトのスカラ型の場合

r10,r11で戻り値を呼び出し側へ返却します。

r10 には下位32ビット,r11 には上位32ビットを設定します。

(c)

構造体や共用体の場合

戻り値が構造体や共用体の場合,呼び出し側は関数呼び出し時に,引数レジスタr6へ戻り値データを書き込む領域のアドレスを設定します。呼び出される側は,パラメータ・レジスタr6で指示されるアドレス位置に戻り値を設定し,呼び出し側関数へと返却します。

返却した時点では,呼び出し側の関数にとっては,r6もr10も不定(他の関数呼び出し前後で内容が保証されないレジスタと同じ)となります。

構造体や共用体は,サイズによらずすべて同じ返却方法となります。構造体や共用体のデータ自体をレジスタに設定して返却することはしません。