以下のアセンブリを理解する方法は?

assembly x86
以下のアセンブリを理解する方法は?
     __asm__ __volatile__ (

            "movl 0x4(%ebp), %eax \n"

            "addl $15, %eax \n"

            "movl %eax, 0x4(%ebp)"

     );

%eax`が戻り値を保存することは知っていますが、%ebp`の目的は何ですか?

  1  0


ベストアンサー

関数のプロローグが次のようになっていると仮定します。

pushl %ebp
movl %esp, %ebp
...

%ebpは、ベースポインター(フレームポインターとも呼ばれます)を格納するレジスタです。 ベースポインターは、スタック内の現在のスタックフレームの開始位置です。 x86の場合、スタックは下方に成長するため、ローカルは%ebpからの負のオフセットとして参照されます。 パラメーターと戻りアドレスは、%ebpからの正のオフセットによって参照されます。 %ebpの値は、スタック(プロローグによってプッシュされた)上の呼び出し元の%ebp値を指します。 これにより、スタックを「ウォーク」するために使用できるベースポインターのリンクリストが効果的に形成されます。 注:これは、各スタックフレームにベースポインターがあることを前提としています。他の用途のために%ebpを解放するフレームポインター省略(FPO)と呼ばれる最適化があります。

そのため、そのプロローグを使用して関数を指定し、呼び出し命令で呼び出された場合(つまり、 呼び出し元の戻りアドレスがスタックにプッシュされました)、0x4(%ebp)は、呼び出し先のプロローグが実行される前にスタックにプッシュされた最後のものであるため、戻りアドレスを格納します。 したがって、コードスニペットを使用すると、呼び出し先が戻った後に次の命令が実行され、呼び出し後の次の命令ではなく、呼び出し元の呼び出し命令の末尾から15バイトになります。

編集:これまでの私の多くの編集は、私の答えをより良く説明するためのものでした。

4


`ebp`はフレームポインターです。 ebpとespは、現在のプロセスのスタックフレームをマークします。

0x4(%ebp)は実際には戻りアドレスであり、この呼び出しが終了した後に関数が返すアドレスです。

この写真のスタックフレームを確認してください。

image:https://i.stack.imgur.com/9sqDG.png [ここに画像の説明を入力]

2


`%ebp`レジスタは、関数パラメーターとローカル変数が保存されている現在の_stack frame_を指します。 そのコードは、%ebpからオフセット0x4の値にアクセスしています(その値が表すものは表示されていません)。

1


ebpはベースポインターです。 スタックに格納された関数パラメーターは、最初にスタックに戻りアドレスがあります。そのため、(32ビットマシンを使用する場合)0x4(%ebp)は関数の最初のパラメーターを指します。

0


タイトルとURLをコピーしました