为什么这个源代码分配了16个字节

Why did this source code allocate 16 bytes?

本文关键字:16个 字节 分配 源代码 为什么      更新时间:2023-10-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


跟进……我读了更多关于堆栈对齐的线程(对不起,我现在正在学习计算机arch和组织课程……)所以我对这个一点也不熟悉)

堆栈分配、填充和对齐

我认为这是编译器的设置。默认情况下,最小值是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

调用栈和栈帧

每个栈帧

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.

但是在从int a分配到int d之后,它已经占用了16个字节。Main没有函数参数,所以是0。但是返回的线路,这些信息去了哪里?

我虽然还没有看到main()的源代码,我相信这是由于堆栈对齐。

在您的设置下,堆栈可能需要对齐到8字节。因此,esp被增加16字节而不是12字节。(即使12字节足以容纳所有变量)

在其他系统上(使用SSE或AVX),堆栈需要对齐到16或32字节。

没有什么不确定的-为返回码分配了前四个字节:)