#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
--------------
答案 0 :(得分:0)
堆栈帧结构是一个实现细节。 C语言标准并未强制要求。所以它可以是任何东西,只要局部变量存在。没有人承诺框架会包含你的局部变量而没有别的。
在这种情况下,保存的EPB和buf
之间有一个未使用的8字节块,而buf
下面有另一块。做什么的?只有编译器知道。也许在调试版本中有一个堆栈保护cookie,但编译器希望在调试版本和发布版本之间保持堆栈帧布局一致。也许有一个对齐/填充要求对于您的函数没有展示的某些场景很重要。