手続きが、どう呼ばれるかを指定します。
呼び出し規則は、対象のコードが、呼ばれたときに、手続きと、どのように相互作用するかを、決定します。
呼び出し規則は、どのように呼び出しスタックにパラメタを押すか、どのように値を返すか、いつ呼び出しスタックを掃除するか、に関する規則を、指定します。
この情報は、他の言語、特にアセンブリ言語で書かれたコードと相互作用するときに、役に立ちます。
いくつかの場合、呼び出し規則は、ある種の名前装飾を、手続き名に、適用します。
FreeBASIC は、3つの呼び出し規則を、サポートします:
stdcall,
cdecl,
pascal
それぞれ、
Stdcall,
Cdecl,
Pascal で指定します。
呼び出し規則は、手続きの宣言か、手続き名の直後の定義かのどちらかで、指定できます。
手続きの宣言は、定義と同じ、呼び出し規則を持たなければなりません。
すべての呼び出し規則の中で、不可欠な手続き戻り値は、
EAX(,
EDX) レジスタで、返されます。そして、浮動小数点の戻り値は、
ST(0) レジスタ(浮動小数スタックの先頭)に、保存されます。
ユーザ定義型 (UDT) の値は、サイズが 8 バイト以下であれば、
EAX(,
EDX) レジスタに、返されます。さもなければ、ユーザ定義型 (UDT) の値は、ユーザ定義型 (UDT) の値のアドレスを、任意のパラメーターの後に、呼び出しスタックに押しつけることにより、メモリに返されます。
stdcall
stdcall 規則では、手続きパラメータは、手続き呼出し(手続き呼出しは、戻りアドレスを、パラメータのちょうど上に押します)に先立って、呼び出しスタックの上に押されます。それらは、宣言された逆順で、つまり右から左に、押されます。
手続きは、呼び出しスタックから、あらゆるパラメータをポップすることを担当しています。(一般に、解放するバイト数を意味する定数を RET 指示に追加することによって)
プラットホーム差:
-
DOS と Windows プラットホームでは、手続き名は、"@N" 接尾語で修飾されます。N は、渡されたパラメタの、バイトの合計サイズです。
cdecl
cdecl 規則では、手続きパラメタは、手続き呼び出しに先立って、パラメータが宣言された逆順で、呼び出しスタックに押されます。すなわち、右から左の順です。
呼ぶコードは、呼び出しスタックから、パラメタを飛び出させることを、担当します。
cdecl は、Linux、*BSDs、DOS上でのデフォルトの呼び出し規則です。
そして、
Extern "C" と
Extern "C++" ブロックの中の、手続きのための、デフォルトの呼び出し規則です。
cdecl は、ほとんどの C と C++ コンパイラで使われるデフォルト規則です。
pascal
pascal 規則では、手続きパラメタは、それらが宣言された順に、呼び出しスタックに押されます。すなわち、左から右です。
手続きは、呼び出しスタックから、パラメタを飛び出させることを、担当します。
pascal は、Pascal と、コンパイラの Microsoft
QuickBASIC シリーズで使われる、デフォルト規則です。
下の表は、それぞれの呼び出し規則の違いを、まとめています:
呼び出し規則 |
パラメタが、 呼び出しスタックに押される順序 |
パラメタを 呼び出しスタックから飛び出させるのは |
stdcall |
右から左に |
手続き |
cdecl |
右から左に |
呼ぶコード |
pascal |
左から右に |
手続き |
プラットホーム差:
-
DOS と Windows プラットホームでは、すべての呼び出し規則は、下線 ("_") 接頭詞を手続き名の前に付けます。
-
デフォルトの呼び出し規則は、プラットホームよって変わります。
Windows は、 stdcall です; Linux、*BSDs、DOS では、cdecl です。
参照: