【发布时间】:2017-08-25 23:45:49
【问题描述】:
这是我的代码
#include <stdio.h>
char func_with_ret()
{
return 1;
}
void func_1()
{
char buf[16];
func_with_ret();
}
void func_2()
{
char buf[16];
getchar();
}
int main()
{
func_1();
func_2();
}
- 我声明了 16 字节的本地缓冲区以保持堆栈指针对齐(对于 x86)。
- 我写了两个函数“func_1”,“func_2”,它们看起来几乎一样——分配16字节的本地缓冲区并调用一个char返回值且没有参数的函数,但一个是自定义的,另一个是getchar ()。
- 使用 gcc 参数“-fno-stack-protector”(因此堆栈上没有金丝雀)和“-O0”进行编译以避免意外的优化行为。
这是 gdb 对 func_1 和 func_2 的反汇编代码。
Dump of assembler code for function func_1:
0x08048427 <+0>: push ebp
0x08048428 <+1>: mov ebp,esp
0x0804842a <+3>: sub esp,0x10
0x0804842d <+6>: call 0x804841d <func_with_ret>
0x08048432 <+11>: leave
0x08048433 <+12>: ret
Dump of assembler code for function func_2:
0x08048434 <+0>: push ebp
0x08048435 <+1>: mov ebp,esp
0x08048437 <+3>: sub esp,0x18
0x0804843a <+6>: call 0x80482f0 <getchar@plt>
0x0804843f <+11>: leave
0x08048440 <+12>: ret
在 func_1 中,为 0x10(16) 字节分配缓冲区, 但是在 func_2 中,它被分配了 0x18(24) 个字节,为什么?
编辑: @Attie 发现两者的缓冲区大小实际上是相同的,但是有 func_2 中奇怪的 8 字节堆栈空间不知道它来自哪里。
【问题讨论】:
-
也许这与
getchar()返回int,而func_with_ret()返回char有关。但归根结底,你为什么要关心? -
我在这两种情况下都得到 16 here。你的编译器是什么?
-
对齐通常不是您在 C 中关心的事情...编译器会为您处理它(如果有必要)。
-
你告诉编译器你想要 16 个元素的空间,它给了你 16 个元素的空间。没有什么可以阻止它在堆栈上留出额外的空间出于自己的目的,无论它们可能是什么(也许是为了
getchar的使用,也许不是)。我不能告诉你为什么它预留了额外的 8 个字节,只是那些额外的 8 个字节不是缓冲区的一部分。