2013-07-07 25 views
12

私は、関数呼び出しがプログラムによって行われたとき、呼び出された関数は呼び出し元に戻る方法を知っていなければならないことを読んでいます。呼び出された後、呼び出された関数はどのように呼び出し元に戻りますか?

私の質問は:呼び出された関数は呼び出し元に戻る方法をどのように知っていますか?コンパイラを使用してバックグラウンドで動作するメカニズムはありますか?

+1

あなたは[this](http://en.wikipedia.org/wiki/Call_stack#Structure)を読むべきです。これは非常に良い答えです:[Chapter 11 - Procedures](http://pages.cs.wisc。あなたがビデオ:[ハッカーのためのAssembly Primer(Part 11)Functions Stack]を好きなら(http://www.progamercity.net/code-tut/168-edu /〜smoler/x86text/lect.notes/procedures.html) assembly-language-primer-hackers-video-series.html)をご覧ください。 –

答えて

12

コンパイラは、ターゲットとするABIの一部として定義された特定の「呼び出し規約」に従います。その呼び出し規約には、システムがどのアドレスに戻るかを知る方法が含まれます。呼び出し規約では、通常、ハードウェアによるプロシージャ呼び出しのサポートが利用されます。

...プロセッサ(CALL命令の次の命令のオフセットが含まれる)EIPレジスタの値をプッシュ:インテルに、例えば、リターン・アドレスがスタックにプッシュされます(後でリターン命令ポインタとして使用するため)関数からの復帰

ret命令を介して行われる:

...プロセッサはEIPレジスタにスタックの最上部からのリターン命令ポインタ(オフセット)ポップし始めます新しい命令ポインタでのプログラム実行。 、ARM上で、リターンアドレスがリンクレジスタに格納されたコントラスト

BLBLX命令がlrに次の命令のアドレスをコピーr14、リンクレジスタ)。

戻り値は通常、movs pc, lrを実行して、リンクレジスタからプログラムカウンタレジスタにアドレスをコピーして戻します。

参考:これは(特にインテルのようなシステム上の)スタックによって可能になる

  1. Intel Software Developers Manual
  2. ARM Information Center
4

。たとえば、ローカルに保持されるintを含むメソッドcallerがあるとします。

caller(target(を呼び出すときは、intを保存する必要があります。これは、コールが行われたアドレスと共に、スタックに置かれます。 target(は、そのロジックを実行し、独自のローカル変数を作成し、他のメソッドを呼び出すことができます。そのローカル変数は、呼び出しのアドレスとともにスタックに配置されます。

target(が終了すると、スタックは「展開」されます。target(のローカル変数を含むスタックの先頭が削除されます。

メソッドが繰り返し発生すると、スタックが大きくなりすぎてスタックオーバーフローが発生することがあります。

8
  1. コンパイラは関数の呼び出し方法と呼び出し規約を知っています。例えば、Cでは関数の引数がスタックにプッシュされます。呼び出し側はスタックをクリアすることができるので、呼び出された関数は引数を削除する必要はありません。他の呼び出し規約には、引数をスタックにプッシュすることが含まれ、呼び出された関数は引数をクリーンアップする必要があります。この場合、生成されたコードは、関数が返す前にスタックを修正するようなものです。呼び出し規約はレジスタ内で引数を渡すことがあるので、呼び出された関数も注意を払う必要はありません。

  2. CPUにはサブルーチンを呼び出す機構があります。これにより、現在の実行アドレスがスタックに格納され、処理が新しいアドレスに転送されます。関数が終了すると、returnステートメントが実行され、呼び出し元のアドレスがフェッチされ、そこで実行が再開されます。

スタックが適切にクリーンアップされていないか、メモリが上書きされているため、リターンアドレスが破棄されると、未定義の動作が発生します。もちろん、正確な実装の詳細は、使用されるプラットフォームによって異なります。

4

これは、呼び出し先と呼び出し元の協力が必要です。

呼び出し元は、呼び出し先が呼び出し先に返すアドレスを(通常はスタックにプッシュするか、レジスタに渡すことで)指定することに同意します。呼び出し先は終了時にそのアドレスに戻ることに同意します実行中。

関連する問題