3

这是一个简单的 C 语言程序,我使用 gdb 对其进行反汇编以了解发生了什么。

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

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

下面是disassemble main对应的汇编代码

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 回答