1

私はちょうど ASM/x86 を学んでいるので、ご容赦ください。

質問

調べているプログラムで次のことに気付きました。呼び出される関数にパラメーターを渡していると思います。

mov   [ebp-04],00000005
call  <some function call here>

私が知る限り、これはスタックの先頭から 2 番目のバイトを value に設定しているようです5

これは効果的に 5 のパラメーターを関数に渡していますか?

の次のようになりますかC?

void someFunction(int num); //function declaration

someFunction(5); //In some context

関数に 5 の 1 つのパラメーターを渡す場合、スタックの一番上ではなく、2 番目のバイト (-04) として設定されるのはなぜですか? スタックの一番上には何がありますか? 私はこれをすべて間違って解釈していますか?

編集 関数の上部は、ebp設定される場所です。

push  ebp
mov   ebp,esp
push  -01
push  184
mov   eax,fs:[00000000]
...   //bunch more pushes and movs with eax and ecx into [ebp-offset]
...   //a couple of jump if equals
...   //some more push and movs
lea   ecx,[ebp-1C]
mov   [ebp-04],00000005
call  <some function>

呼び出された関数は次のとおりです。

 mov   edx,[ecx]
 mov   eax,[ecx+08]
 sub   eax,edx
 test  edx,edx
 je    <label1>
 cmp   eax,00000080
 jna   <label2>
 push  edx
 call  <another function>
 add   esp,04
 ret
label2:
 push  eax
 push  edx
 call  <yet another function>
 add   esp,08
label1:
 ret
4

3 に答える 3

1

ebpはスタック ポインタではありませんespebp慣習的にフレームポインタとして使用されるため、設定方法によっては、実際にそれ5を引数として渡す場合があります。または、ローカル変数に格納しているだけかもしれません。

また、関数自体を知らなければ、それがローカル引数か関数引数かを判断できない場合があります。

int x = 5;
foo();

と同じコードを生成する可能性がありますfoo(5);

フレーム ポインターは、現在の関数のスタック領域の先頭を指すために使用され、プロローグで関数自体によって設定する必要があります。引数はその上にあり (正のオフセット)、ローカルはその下にあります (負のオフセット)。esp32 および 64 ビット モード (x86) では、スタック ポインターを基準にして直接アドレス指定できるため、実際には必要ないことに注意してください。それでも、デバッグ目的など、状況によっては役立つ場合があります。

于 2013-10-15T17:43:36.367 に答える
1

通常、パラメーターは、レジスターに入れるか、スタックにプッシュしてから、対象のサブルーチンを呼び出すことによって渡されます。

EBP には、多くの場合、スタック トップではなく、スタック フレームへのポインターが含まれます。したがって、あなたの例は奇妙に思えますが、少なくとも引数を渡す操作である可能性は低いようです。呼び出しが行われている関数に関連する他のアクションである可能性があります。

コンパイラが生成したコードですか?その場合、コンパイラは ESP と EBP の関係を認識している可能性があり (多くの場合、関数 ESP の入力が ESP にコピーされる場合)、その知識を利用している可能性があります。使用されている EBP 値がどこに設定されているかを事前に把握する必要があります。そのコードを表示すると役に立ちます。

于 2013-10-15T17:44:36.543 に答える