为什么这个源代码分配16个字节?
(gdb) disas /m main
Dump of assembler code for function main():
2 {
0x080483f4 <+0>: push %ebp
0x080483f5 <+1>: mov %esp,%ebp
0x080483f7 <+3>: sub $0x10,%esp
3 int a = 1;
0x080483fa <+6>: movl $0x1,-0x4(%ebp)
4 int b = 10;
0x08048401 <+13>: movl $0xa,-0x8(%ebp)
5 int c;
6 c = a + b;
0x08048408 <+20>: mov -0x8(%ebp),%eax
0x0804840b <+23>: mov -0x4(%ebp),%edx
0x0804840e <+26>: lea (%edx,%eax,1),%eax
0x08048411 <+29>: mov %eax,-0xc(%ebp)
7 return 0;
0x08048414 <+32>: mov $0x0,%eax
8 }
0x08048419 <+37>: leave
注意第三条汇编指令,它分配了 16 个字节,而不是预期的 12 个字节。这是为什么?我以为第三行是分配自动变量...
即使我删除了分配,分配仍然是16字节。
谢谢。
编辑
// no header. nothing
int main()
{
int a = 1;
int b = 10;
int c;
c = a + b;
return 0;
}
g++ -g -o demo demo.cpp
跟进... 我读了更多关于堆栈对齐的线程(抱歉,我现在正在学习计算机架构和组织类......所以我对此根本不熟悉)
我认为这是编译器的设置。所以默认情况下,最小值是 16 字节。
如果我们有
int a = 1;
int b = 10;
int c = 10;
int d = 10;
// --
int e = 10;
最多 int d,我们将恰好有 16 个字节,并且分配仍然是 0x10。但是当我们给出另一个选择时,int e = 10,esp 现在被分配了 32 个字节(0x20)。
这表明 esp(堆栈指针)仅用于自动变量。
后续2
调用栈和栈帧
各个栈帧
新调用函数的所有自动变量的存储空间。 当被调用函数返回时要返回的调用函数的行号。 被调用函数的参数。
但是在我们分配了 int a 到 int d 之后,它已经占用了 16 个字节。 Main 没有函数参数,因此为零。但是返回的线路,这些信息到哪里去了?
(gdb) disas /m main
Dump of assembler code for function main():
2 {
0x080483f4 <+0>: push %ebp
0x080483f5 <+1>: mov %esp,%ebp
0x080483f7 <+3>: sub $0x10,%esp
3 int a = 1;
0x080483fa <+6>: movl $0x1,-0x4(%ebp)
4 int b = 10;
0x08048401 <+13>: movl $0xa,-0x8(%ebp)
5 int c;
6 c = a + b;
0x08048408 <+20>: mov -0x8(%ebp),%eax
0x0804840b <+23>: mov -0x4(%ebp),%edx
0x0804840e <+26>: lea (%edx,%eax,1),%eax
0x08048411 <+29>: mov %eax,-0xc(%ebp)
7 return 0;
0x08048414 <+32>: mov $0x0,%eax
8 }
0x08048419 <+37>: leave
Notce the 3rd assembler instruction, it allocated 16 bytes instead of the expected 12 bytes. Why is that? I thought the 3rd line is allocating automatic variables...
Even if I removed the assignment, the allocation is still 16 bytes.
Thanks.
Edit
// no header. nothing
int main()
{
int a = 1;
int b = 10;
int c;
c = a + b;
return 0;
}
g++ -g -o demo demo.cpp
Follow up...
I read a couple more threads on stack alignment (sorry, I am now studying computer arch and organization class...so I am not familiar with this at all)
Stack Allocation Padding and Alignment
I am supposed it's the compiler's setting. So default, the minimum is 16-byte.
If we have
int a = 1;
int b = 10;
int c = 10;
int d = 10;
// --
int e = 10;
Up to int d, we would have exactly 16-bytes, and the allocation is still 0x10. But when we give another delectation, int e = 10, esp is now allocated 32 bytes (0x20).
This shows me that esp, the stack pointer, is only used for automatic variables.
Follow-up 2
Call stack and Stack frame
Each stack frame
Storage space for all the automatic variables for the newly called function. The line number of the calling function to return to when the called function returns. The arguments, or parameters, of the called function.
But after we allocated int a through int d, it already took us 16 bytes. Main has no function parameters, so that's zero. But the line to return, where did this information go?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
虽然我还没有看到我相信这是由于堆栈对齐造成的。main()
的源代码,根据您的设置,堆栈可能需要对齐到 8 字节。因此,
esp
会增加 16 个字节,而不是 12 个字节。 (即使 12 字节足以容纳所有变量)在其他系统(使用 SSE 或 AVX)上,堆栈需要与 16 或 32 字节对齐。
I although I haven't seen the source code forI believe this is due to stack alignment.main()
yet,Under your settings, the stack probably needs to be aligned to 8 bytes. Therefore
esp
is being incremented by 16 bytes rather than 12 bytes. (even though 12 bytes is enough to hold all the variables)On other systems (with SSE or AVX), the stack will need to be aligned to 16 or 32 bytes.
没有什么神秘的 - 前四个字节分配给返回代码:)
Nothing mistical - first four bytes are allocated for return code :)