6

私はこのトピックがここやインターネット上の他の場所で取り上げられていることを知っていますが、うまくいけば、私が集会に頭を悩ませようとしているので、質問は単純なものです...

したがって、正しく理解していれば、ebp(ベースポインター)はスタックの一番上を指し、esp(スタックポインター)は一番下を指します-スタックが下に成長するためです。したがって、espは「現在の場所」を指します。したがって、関数呼び出しでは、スタックにebpを保存したら、関数用の新しいスタックフレームを挿入します。したがって、下の画像の場合、N-3から開始した場合は、関数呼び出しを使用してN-2に移動します。しかし、あなたがN-2にいるとき、あなたのebp==25とesp==24ですか(少なくとも最初は、データがスタックに配置される前に)?

これは正しいですか、それとも私はここで接線を外れていますか?

ありがとう!

http://upload.wikimedia.org/wikipedia/en/a/a7/ProgramCallStack2.png
(出典:wikimedia.org

4

3 に答える 3

4

これは実際には、ハードウェアアーキテクチャとコンパイラだけでなく、呼び出し規約にも依存します。これは、関数がスタックと連携して相互に呼び出すための合意された方法です。#pragmaつまり、コンパイラの設定(および固有のオプションなど)に応じて、関数がスタックに物事をプッシュできる順序が異なります。

cdeclx86アーキテクチャの呼び出し規約について話しているようです。その場合、発信者ebpは通常、リターンアドレスの直後にスタックにプッシュされます。したがって、この例のN-2では、場所25には呼び出し元の関数N-3へのポインターが含まれ(つまり、N-2に入った直後の命令のアドレスが含まれますcall)、場所24には次のようになります。古いebp、そしてあなたのespは、呼び出しの直後、ローカルがスタックにプッシュされる前に=23になります。(一部のコンパイラーは、呼び出しの直後にスタックにスペースを作成するため、関数N-2内で上下に移動する代わりに、ESPは20になります。)

ただし、x86には、特定の条件下で古いものをスタックに完全にプッシュすることを回避する、フレームポインターの省略と呼ばれる、コンパイラーが実行できる特定の最適化があることに注意してください。ebp

于 2010-04-28T01:54:31.000 に答える
3
  1. を呼び出した後N-3、、、およびebpです 。28esp25
  2. 古いebpものがプッシュされ、次に、ebpが現在の値のに設定されますesp。今は両方espebpです24
  3. 最後に、espローカル変数用のスペースを作るために調整されます。を呼び出すときの関数の動作に応じて、 esp現在は可能性があります。20N-2

これを回避するための最良の方法は、関数プロローグについて読み、x86の実装に慣れることです。また、それを受け入れるのに役立ち、コンパイラ、アーキテクチャ、プラットフォーム間で多少の違いがespありebpますが、各関数でスタックの使用をローカライズするために使用されます(C以上のレベルの言語のユーザーにはほとんど関係ありません)。

于 2010-04-28T01:55:02.207 に答える
1

プラットフォームによって異なりますが、これが一般的に機能する方法です。

私が最もよく知っているアーキテクチャでは、「呼び出し元」(別名return)アドレスは$ raレジスタにあり、スタックは呼び出し元が残した場所にあります。つまり、(呼び出し元の)ベースポインタと同様に、リターンアドレスがスタックにプッシュされ、スタックが存在する場所を指すようにベースポインタが更新され、スタックがクロールし続けます。物事がプッシュされる場所の正確な順序と、思い出せないときに設定されるものですが、通常は、破壊されるレジスターを保存するのは呼び出し先の責任です。そうすれば、呼び出される関数が1つまたは2つのレジスタのみを使用する場合、呼び出し元の関数はすべてを保存する必要はありません。(実際には、リターンアドレスレジスタは同じです。関数が他に何も呼び出さない場合、スタックにプッシュされることはありません。)

プログラムを分解して関数プロローグとエピローグを覗いてみると、これは実際には非常に簡単に理解できます。それらはすべて、上部に「すべてを保存」、下部に「すべてを復元」という非常に一般的なパターンに従います。(保存または復元されない「特殊」レジスターが存在する場合があり、コンパイラーは、関数呼び出しがない場合にのみコヒーレントな値を期待できることを認識していることに注意してください。MIPSでは、それらはSレジスターだと思います。そしてPPCはそれらをtと呼びますか?)

于 2010-04-28T01:39:03.427 に答える