3

これは、何が起こっているのかを理解するために gdb を使用して逆アセンブルした C の簡単なプログラムです。

#include <stdio.h>
#include <string.h>
int main(){
    printf("%d", sizeof(foo("HELLOWORLD")));
}

int foo(char* c)
{
   printf("%s\n",c);
}

以下は、逆アセンブルメインの対応するアセンブリコードです

0x08048414 <+0>:    push   %ebp
   0x08048415 <+1>: mov    %esp,%ebp
   0x08048417 <+3>: and    $0xfffffff0,%esp
   0x0804841a <+6>: sub    $0x10,%esp
   0x0804841d <+9>: mov    $0x8048520,%eax
   0x08048422 <+14>:    movl   $0x4,0x4(%esp)
   0x0804842a <+22>:    mov    %eax,(%esp)
   0x0804842d <+25>:    call   0x8048320 <printf@plt>
   0x08048432 <+30>:    leave  
   0x08048433 <+31>:    ret   

そして以下は逆アセンブルfooです

0x08048434 <+0>:    push   %ebp
   0x08048435 <+1>: mov    %esp,%ebp
   0x08048437 <+3>: sub    $0x18,%esp
   0x0804843a <+6>: mov    0x8(%ebp),%eax
   0x0804843d <+9>: mov    %eax,(%esp)
   0x08048440 <+12>:    call   0x8048330 <puts@plt>
   0x08048445 <+17>:    leave  
   0x08048446 <+18>:    ret  

これらの指示について混乱しています:

  1. 0x08048417 <+3> and $0xfffffff0,%esp 前に変更されていないのに、なぜスタックポインタを整列させる必要があるのですか?

  2. 0x0804841a <+6>:sub $0x10,%esp この命令は、プログラムに固有のことを正確に何をしていますか?

  3. 0x0804841d <+9>:mov $0x8048520,%eax この命令は、プログラムに固有の何をしていますか?

  4. mov %eax,(%esp) 丸括弧 とは%espどういう意味ですか?

誰かがこれを説明してくれれば助かります。

4

1 に答える 1

2
  1. (関数-) プロローグに属し、SP をビットマスクすることにより、SP を 16 バイト境界に合わせます。

  2. ポインタを関数に渡す必要があるため、スタック フレームのメモリが作成されます。アドレスはスタックから関数に渡されます。ただし、式はコンパイル時に評価されるように見えるため、実際の呼び出しは必要ありません。

  3. 0x8048520おそらく文字列「%d」のアドレスです。それは eax に入れられ、そこからスタックポインターを使用してスタックに入れられます。

このように、周りにはたくさんの資料があります。

于 2013-02-28T13:37:20.097 に答える