0
#define NORMAL_BUFFER_SIZE 32 
int getbuf()
{
    char buf[NORMAL_BUFFER_SIZE];
    Gets(buf);
    return 1;
}

我有一个这样的 C 代码,它应该在堆栈中分配 32 个字节。

拆开的时候,

0804919e <getbuf>:
 804919e:   55                      push   %ebp
 804919f:   89 e5                   mov    %esp,%ebp
 80491a1:   83 ec 38                sub    $0x38,%esp
 80491a4:   8d 45 d8                lea    -0x28(%ebp),%eax
 80491a7:   89 04 24                mov    %eax,(%esp)
 80491aa:   e8 ef f9 ff ff          call   8048b9e <Gets>
 80491af:   b8 01 00 00 00          mov    $0x1,%eax
 80491b4:   c9                      leave  
 80491b5:   c3                      ret    
 80491b6:   90                      nop
 80491b7:   90                      nop

我得到这样的东西,我可以看到它首先将 $0x38 字节分配到堆栈上,然后将 buf 传递给 Gets,因为 buf 是一个数组,它将基指针传递给 Gets。buf 的大小为 32 字节,即十六进制的 0x20,那么为什么它不传递 lea -x020(%ebp), %eax?

据我所知,堆栈的结构应该是这样的

--------------
ret addr
--------------
old ebp
--------------
32 bytes for
buf
--------------
something else
here
--------------
4

1 回答 1

1

栈帧结构是一个实现细节。C 语言标准没有强制要求。所以它可以是任何东西,只要有局部变量。从来没有人承诺框架将包含您的局部变量,仅此而已。

在这种情况下,您在保存的 EPB 和 之间有一个未使用的 8 字节块buf,并且在buf. 做什么的?只有编译器知道。也许在调试版本中有一个堆栈保护cookie,但编译器希望在调试和发布版本之间保持堆栈框架布局一致。也许有一个对齐/填充要求,这对于您的函数未展示的某些场景很重要。

于 2013-09-30T17:16:36.923 回答