seclan のほえほえルーム

| |

・C 言語の関数呼び出し形式 (1999/07/28 [])
 以前に関数の呼び出し形式を紹介しました。そのなかで C 言語の呼び出し形式がありました。_cdecl を関数に修飾すればそれを指定できます。C 言語ではこの呼び出し方が標準なので、普通に使うぶんにはあらためて _cdecl を指定する必要はありません。では具体的にはどのように呼び出されるのでしょうか。ただしここで挙げるのは C 言語の規格ではなく、一つの実装例であることに気をつけてください。

//(1)関数のプロトタイプ
void _cdecl foo(int x, int y);

//(2)関数呼び出しの例
foo( 1, 2);

//(3)具体的な 80386 アセンブリ言語に
//  よる呼び出しプログラム例
0000: push 2
0001: push 1
0002: call _foo
0003: add  esp, 4*2

 (1)で示される関数を、(2) のように呼び出すことを考えます。するとその具体的な呼び出し方法は (3) のようになります。まず C 言語では引数は 0 行目、1 行目のように、右から左の引数順にスタックに積まれます。次に、_cdecl で宣言された関数の名前は先頭に _ が付く名前に変形されます。従ってこの場合は、foo は _foo となります。2 行目で foo 関数を呼びます。関数から返ってきたら、引数がまだスタックに残っているので、3 行目で示すように、呼び出した側でスタックを調整することで引数を捨てます(スタックにプッシュした値の大きさが 4 byte × 2 個)。
 関数を呼び出すたびにこのようなコードが毎回実行されます。したがって、この呼び出しコード部分を早くすることで、プログラムの実行を高速化することが可能になります。
 ちなみに C 言語がこのような一見非効率な呼び出し方を取っている理由は、可変長引数(printf のような関数の引数)を特別な指示無しに実現するためです。


by seclan


| |

 

配信

3.98 msec