9.1.3 実引数の受け渡し

(1)

実引数の受け渡しに利用可能なレジスタ

実引数の受け渡しに利用可能なレジスタはAX,BC,およびDEです。

(2)

実引数の割り付け対象と実引数の型・サイズの変更

実引数の割り付け対象と実引数の型,およびサイズをどのように変更するかを以下に示します。

ここに記述したもの以外は変更を受けません。

実引数の種類

実引数の割り付け対象

実引数の型・サイズの変更

関数原型が参照でき,仮引数の型が参照できる場合

レジスタ,またはスタック

farポインタをレジスタに割り付ける場合は3バイト分のレジスタに割り付けます。

関数原型が参照でき,仮引数の型が参照できない場合(=可変個引数)

スタック

既定の実引数拡張に従います。

関数原型が参照できない場合

レジスタ,またはスタック

既定の実引数拡張に従います。

既定の実引数拡張の結果,farポインタをレジスタに割り付ける場合は3バイト分のレジスタに割り付けます。

注意 1.

変数のサイズや既定の実引数拡張については「(7) 既定の実引数拡張」を参照してください。

注意 2.

可変個引数の直前の実引数は「関数原型が参照でき,仮引数の型が参照できる場合」として扱います。

(3)

実引数のレジスタへの割り付け

実引数のレジスタへの割り付けは,以下のようになります。

-

レジスタに割り付ける候補となるのは4バイト以下のサイズの実引数です。
ただ,構造体型,および共用体型の実引数がレジスタに割り付く場合,構造体型,および共用体型に含まれるパディングもレジスタに割り付けられます。

-

実引数が構造体,または共用体の場合,すべてのメンバがレジスタに割り付けられるか,スタックに割り付けられるかのどちらか一方です。

-

farポインタはその下位3バイトをレジスタに割り付けます。
farポインタにおけるページ番号部分(=farアドレス20ビットの上位4ビット)は下位3バイトのうちの上位1バイトが割り付くレジスタの下位4ビットに格納します。
例えば,farポインタをA-DEに割り付ける場合,ページ番号部分はAレジスタの下位4ビットに格納されます。

-

実引数は第1引数から最後の引数の順(プログラム上,左から右の順)に,利用可能なレジスタのうち最も優先順位の高いレジスタに割り付けられます。利用可能なレジスタがない場合,その実引数はスタックに割り付けられます。優先順位を以下に示します。

実引数のサイズ

割り付けるレジスタの優先順位(左側ほど優先順位が高い)

1バイト

A,X,C,B,E,D

2バイト

AX,BC,DE

3バイト

C-AX,X-BC,E-BC,X-DE,B-DE

4バイト

farポインタ: A-DE,X-DE,C-DE,B-DE,X-BC

farポインタ以外: BC-AX,DE-BC

 

この表で“-”は,8ビット,または16ビット・レジスタとほかの16ビット・レジスタを結び付ける記号です。

各引数のレジスタへの割り付けは,引数を構成するバイトのアドレス降順(大きいアドレスから小さいアドレスの順)が上記の表に指定されたレジスタの指定順(左から右の順)に一致するように割り付けられます。

例 1.

void foo(char p1, short p2, char p3) を呼び出すとき,p1をAに, p2をBCに, p3をXに割り付けます。

例 2.

以下の構造体型の実引数Sがレジスタに割り付く時,c1はXに,s2はBCに割り付けられます。Aにはパディングが割り付きます。

struct {
        char    c1;
        short   s2;
} S;

例 3.

void foo(long x)を呼び出すとき,xの上位2バイトはBCレジスタ,下位2バイトはAXレジスタに割り付けます。

例 4.

以下の構造体型の実引数S3がレジスタに割り付く時,最上位バイトはCレジスタ,次の1バイトはAレジスタ,最下位バイトはXレジスタに割り付けられます。

struct{
        char    a[3];
} S3;

注意 1.

long long,および-dbl_size=8の時のdouble等の8バイト・データはスタックに割り付けられます。

注意 2.

5バイト以上の構造体や共用体はスタックに割り付けられますが,4バイト以下の構造体や共用体はレジスタに割り付ける候補となります。

(4)

実引数のスタックへの割り付け

実引数のスタックへの割り付けは,以下のようになります。

-

スタックで渡す実引数自体はリトル・エンディアンで配置し,2バイト境界にアラインされます。

-

スタックで渡す実引数の配置順序は,実引数並びにおいて,より左側にある実引数がより小さいアドレスになるように配置されます。

-

スタックで渡す実引数の配置は,実引数間に1バイトのパディングが入ることを除けばスタック内に連続して配置されます。

-

各引数のスタックへの割り付けは,引数を構成するバイトのアドレス降順(大きいアドレスから小さいアドレスの順)がスタックのアドレス降順(大きいアドレスから小さいアドレスの順)に一致するように割り付けられます。

-

farポインタは,その下位3バイトをスタック上の4バイトの領域に割り付けられます。4バイトのうちの上位1バイトの値は不定です。farポインタにおけるページ番号部分(=farアドレス20ビットの上位4ビット)は4バイトの領域中の上位から2バイト目の下位4ビットに割り付けられます。

 

注意

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

 

-

スタックに割り付ける実引数は以下です。

-

1バイトから4バイトのサイズの実引数でレジスタに割り付けないもの

-

5バイト以上のサイズの実引数

-

可変個の実引数

 

void foo(long long x)を呼び出すとき,スタック・ポインタをspとすると,xの最上位1バイトはsp+7が指す位置へ割り付け,以降,各バイトをアドレスの降順にsp+6,sp+5,sp+4,sp+3,sp+2,sp+1へ割り付け,最下位バイトはsp+0が指す位置へ割り付けられます。