アセンブラー・レベルのサブルーチンのリンケージ規約

サブルーチン・リンケージ規約は、サブルーチンの入り口と出口での マシンの状態を指定し、同じ言語または異なる言語で別個にコンパイルされる ルーチンのリンクを許可します。 「System V Application Binary Interface: PowerPC Processor Supplement」および「64-bit PowerPC ELF Application Binary Interface Supplement」 に記載されているサブルーチン・リンケージおよびシステム呼び出しに関する情報は、この項目に関する基本的な 説明になっています。 完全な詳細を知るために、これらの情報を 参照してください。 本節は、混合言語 Fortran およびアセンブラー・プログラムを作成したり、アセンブラー・レベルで デバッグするのに必要な情報を要約したもので、この種の基礎知識は持っておかなければなりません。

システム・リンケージ規約は、多数の浮動小数点レジスター (FPR) と汎用レジスター (GPR) を最大限に 利用して、サブルーチンの入り口と出口でのレジスターの保管と復元を最小化して、レジスター内の引き数を 渡します。 このリンケージ規約は、引き数の引き渡しおよび戻り値が FPR か GPR、またはその両方に入ることが許可されます。

次の表は、浮動小数点レジスターと、それらの機能をリストしたものです。 浮動小数点レジスターは、倍精度です (64 ビット)。

表 22. 呼び出し間の浮動小数点レジスターの使用法

レジスター 呼び出し間での保存 使用法
0 なし  
1 なし FP パラメーター 1、関数戻り 1
2 なし FP パラメーター 2、関数戻り 2
3 なし FP パラメーター 3、関数戻り複素数 *32
4 なし FP パラメーター 4、関数戻り複素数 *32

·
·
·

·
·
·

·
·
·
8 なし FP パラメーター 8
9-13 なし
14-31 あり ローカル変数

次の表は、汎用レジスターと、それらの機能をリストしたものです。

表 23. 呼び出し間の汎用レジスターの使用法

レジスター 呼び出し間での保存 使用法
0 なし  
1 あり スタック・ポインター
2 あり システム予約済み。
3 なし 引き数リストの 1 番目のワード、戻り値 1
4 なし 引き数リストの 2 番目のワード、戻り値 2
5 なし 引き数リストの 3 番目のワード

·
·
·

·
·
·

·
·
·
10 なし 引き数リストの 8 番目のワード
11-12 なし
13 あり SDA ポインター
14-30 なし ローカル変数
31 あり ローカル変数または「環境ポインター」
レジスターが保持すると示されていないものは、呼び出し中に内容を 変更することができます。呼び出し元は責任を持って、 後で値が必要になるレジスターを保管する責任があります。 逆に言えば、レジスターが保持されると考えられる場合は、 呼び出し先が呼び出し間で内容を保持する責任があり、 呼び出し元は特別な処置を行う必要はありません。

次の表は、特殊目的のためのレジスター規約をリストしたものです。

表 24. 呼び出し間の特殊目的レジスターの使用法

レジスター 呼び出し間での保存
条件レジスター
ビット 0-7 (CR0,CR1)
ビット 8-22 (CR2,CR3,CR4)
ビット 23-31 (CR5,CR6,CR7)
 
なし
あり
なし
リンク・レジスター なし
カウント・レジスター なし
XER レジスター なし
FPSCR レジスター なし

スタック

スタックは、ローカル・ストレージ、レジスター保管域、パラメーター・リスト、呼び出しのチェーン・データを 保持するのに使用されるストレージの一部です。 スタックは高位アドレスから低位アドレスに向かって広がります。 スタック・ポインター・レジスター (レジスター 1) は、スタックの現在の「最上位」を示すのに使用されます。

スタック・フレームは、1 つのプロシージャーで使用されるスタックの部分です。 入力パラメーターは、現在のスタック・フレームの一部と見なされます。 ある意味では、個々の出力引き数は、呼び出し元のスタック・フレームと呼び出し先のスタック・フレームの 両方に属しています。 どちらの場合にも、スタック・フレーム・サイズは呼び出し元のスタック・ポインターと呼び出し先のスタック・ポインターとの違いとして最適化を図って定義されます。

以下の図は、32 ビットおよび 64 ビット環境での典型的なスタック・フレームのストレージ・マップを示しています。

これらの図では、 現行ルーチンは他の関数を呼び出せるようにするスタック・フレームを獲得しています。 ルーチンが呼び出しを行わず、ローカル変数または一時変数が存在しない場合で、 不揮発性レジスターを保管する必要がなければ、関数がスタック・フレームを割り振る必要はありません。 必要であれば、呼び出し元のスタック・フレームの先頭にあるレジスター保管域をその後も使用することができます。

スタック・フレームは、 ダブルワード 境界に位置合わせされます。



                      32 ビット環境の実行時スタック
 
 
  高位                |                    |
  アドレス            |                    |
                      |--------------------|
呼び出し元の -->      |   逆方向チェーン   |
スタック・ポインター  |                    |
                      |                    |
                      |--------------------|
                      |                    |
         -8*nfprs --> | 呼び出し元の FPR 用| Ffirst = F14 (完全な
                      |       保管域       |          保管の場合)
                      |最大 18 ダブルワード| F31
                      |                    |
                      |--------------------|
                      |                    |
 -8*nfprs-4*ngprs --> | 呼び出し元の GRP 用| Rfirst = R14 (完全な
   保管               |       保管域       |          保管の場合)
                      |    最大 18 ワード  | R31
                      |                    |
                      |--------------------|
                      |                    |
                      |       CR 用        |
                      |      保管域        |
                      |                    |
                      |--------------------|
                      |                    |
                      |      ローカル      |
                      |                    |
                      |--------------------|
                      |                    |
 レジスターに入らない |         Pn         |  出力引き数域
 パラメーターのための |        ...         | <---(引き数リストを作成
 スペース             |         P9         |      するために呼び出し先が
                      |                    |      使用)
                      |--------------------|
                      |                    |
                    4 |    保管された LR   | <-----+
                      |                    |       |
                      |--------------------|       最小スタック・フレーム
                      |                    |       「リンク域」
呼び出し先の    --> 0 |   逆方向チェーン   | <-----+
スタック・ポインター  |                    |
                      |--------------------|
                      |                    |
  低位                |                    |   スタックはこの端から
  アドレス            |                    |   増大します
 



                      64 ビット環境の実行時スタック
 
  低位                |                    |   スタックはこの端から
  アドレス            |                    |   増大します
                      |--------------------|
呼び出し先の    --> 0 |   逆方向チェーン   |
スタック・          8 |   保管された CR    |
ポインター         16 |   保管された LR    |
                24-32 |      予約済み      | <--- リンク域
                   40 |   保管された TOC   |         (呼び出し先)
                      |--------------------|
 P1-P8 用のスペースは |         P1         |        出力引き数域
 常に予約されています |        ...         | <---(引き数リストを作成する
                      |         Pn         |         ために呼び出し先が
                      |--------------------|         作成します)
                      |    呼び出し先の    |
                      |     スタック域     | <--- ローカル・
                      |                    |         スタック域
                      |--------------------|
                      |                    | (境界合わせのために浪費される
                      |--------------------|  可能性のあるワード)
 -8*nfprs-8*ngprs --> | 呼び出し元の GPR 用| Rfirst = R13 (完全な
   保管               |      保管域        |               保管の場合)
                      |最大 19 ダブルワード| R31
                      |--------------------|
         -8*nfprs --> | 呼び出し元の FPR 用| Ffirst = F14 (完全な
                      |       保管域       |               保管の場合)
                      |最大 18 ダブルワード| F31
                      |--------------------|
呼び出し元の    --> 0 |   逆方向チェーン   |
スタック・          8 |   保管された CR    |
ポインター         16 |   保管された LR    |
                24-32 |      予約済み      | <--- リンク域
                   40 |   保管された TOC   |         (呼び出し元)
                      |--------------------|
P1-P8 用のスペース 48 |         P1         |  入力パラメーター域
は常に予約されています|        ...         | <---(呼び出し先の入力
                      |         Pn         |         パラメーターがここに
                      |--------------------|         入っています。また、
                      |    呼び出し元の    |         呼び出し元の引き数域でも
                      |    スタック域      |         あります)
  高位                |                    |
  アドレス            |                    |

リンク域および最小スタック・フレーム

32 ビット環境では、リンク域は 2 ワードで構成され、プロシージャーへの 入り口の呼び出し先のスタック・ポインターからオフセット 0 にあります。 最初のワードには、呼び出し元の逆方向チェーン (前のスタック・フレームへのポインター) が含まれています。 2 番目のワードは、必要な場合に呼び出し元がリンク・レジスター (LR) を保管するロケーションです。

64 ビット環境では、この区域は 6 個のダブルワードで構成され、 プロシージャーへの入り口の呼び出し元のスタック・ポインターからオフセット 0 にあります。 最初のダブルワードには、呼び出し元の逆方向チェーン (スタック・ポインター) が含まれています。 2 番目のダブルワードは、必要な場合に呼び出し先が条件レジスター (CR) を保管するロケーションです。 3 番目のダブルワードは、必要な場合に呼び出し先の prolog コードがリンク・レジスターを保管する ロケーションです。 4 番目のダブルワードは、C SETJMP および LONGJMP 処理用に予約されていて、5 番目の ダブルワードは将来の使用に備えて予約されています。 最後のダブルワード (ダブルワード 6) は、他のオブジェクト・モジュール (たとえば共用ライブラリー) 内の ルーチンを呼び出す時に使用されるグローバル・リンケージ・ルーチン用に予約されています。

入力パラメーター域

32 ビット環境では、レジスターに入らない入力パラメーターは、出力引き数域 (P9... Pn) に入ります。

入力パラメーター域は、64 ビット環境では、呼び出し先の 入力パラメーターのレジスター・イメージを表すために、呼び出し側プログラムによって予約されるストレージの 連続部分です。 入力パラメーター域は、ダブルワード境界に合わせられ、呼び出し元のリンク域の直後のスタックに入れられます。 この区域のサイズは、最低でも 8 ダブルワードあります。 8 ダブルワードを超えたパラメーターが予期される場合は、入力スタック・ポインターからの正方向オフセット 112 から始まるレジスター・イメージとして保管されます。

最初の 8 ダブルワードは、呼び出し点でレジスターに現れるだけで、 スタックには現れません。 残りのワードはスタックに常に入っていて、レジスターに入れることもできます。

レジスター保管域

32 ビット環境では、レジスター保管域は、呼び出し先のプログラムで使用されるすべての不揮発性 FPR および GPR を保管するために必要なスペースを提供します。 FPR は呼び出し元の最小スタック・フレームの隣に保管されます。 GPR は FPR の下 (低位アドレス) に保管されます。

64 ビット環境では、レジスター保管域は、 ダブルワード境界に合わせられます。 呼び出し先のプログラムで使用されるすべての不揮発性 FPR および GPR を保管するのに必要なスペースを提供します。 FPR はリンク域の隣りに保管されます。 GPR は FPR の下 (低位アドレス) に 保管されます。 呼び出された関数は、新しいスタック・フレームを割り振る必要がない場合でも、ここにレジスターを保管することができます。 システム定義のスタック・フロアには、以下のような可能な最大の保管域が含まれています。

   32-bit platforms:  18*8 for FPRs + 18*4 for GPRs
   64-bit platforms:  18*8 for FPRs + 19*8 for GPRs

呼び出し先が行わなければならないことは、実際に使用する不揮発性レジスターの保管だけです。

ローカル・スタック域

ローカル・スタック域は、ローカル変数および 一時変数用に呼び出し先のプロシージャーが割り振るスペースです。

出力パラメーター域

32 ビット環境では、レジスターに入らない入力パラメーターは、出力引き数域 (P9... Pn) に入ります。

8 ワードを超えて渡される場合は、現行スタック・ポインターからのオフセット 8 から始まる拡張リストが作成されます。

最初の 8 ワードは、呼び出し点でレジスターに現れるだけで、スタックには現れません。 残りのワードはスタックに常に入っていて、レジスターに入れることもできます。

64 ビット環境では、出力パラメーター域 (P1...Pn) には、 このスタック・フレームを所有しているプロシージャーが呼び出すすべてのプロシージャーの最大の パラメーター・リストを保持できるだけの十分な大きさが必要です。 この域の長さは、引き数リストの長さまたは存在とは無関係に、最低でも 8 ダブルワードあります。 8 ダブルワードを超えて渡される場合は、現行スタック・ポインターからのオフセット 112 から始まる 拡張リストが作成されます。

最初の 8 ダブルワードは、呼び出し点でレジスターに現れるだけで、 スタックには現れません。 残りのダブルワードはスタックに常に入っていて、レジスターに入れることもできます。 IBM Copyright 2003