为什么这个源代码分配了16个字节
Why did this source code allocate 16 bytes?
(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字节。
没有什么不确定的-为返回码分配了前四个字节:)
相关文章:
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 更改高度贴图,使其在 4x4 网格上显示 16 个 hieghtmap
- 为什么 bool 和 _Bool 如果它们在内存中占用 1 个字节,它们只能存储 0 或 1
- 在 Linux 中,uint32_t从 4 个字节更改为 6 个字节
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 向指针地址添加 20 个字节偏移量
- 为什么在我的实现中,所有数组都对齐到 16 个字节?
- AES-128 CFB-8解密的前16个字节已损坏
- 为什么分配的变量地址之间相差 16 个字节?
- 如何创建 std::vector of char/std::byte,其中第一个字节对齐到 16 个字节,但没有填充
- 将分配的前 16 个字节的内存强制转换为 UDT
- _declSpec(Align(16))不将指针与16个字节对齐
- AES CBC 加密/解密仅解密前 16 个字节
- 如何从字符串中每隔16个字节复制一次数据
- 如何在使用高达 SSSE3 的内部函数后存储 16 字节寄存器中的 4 个字节
- 使用 AES 解密时错误的 16 个字节
- 使用AES解密时,前16个字节已损坏
- 为什么这个源代码分配了16个字节
- 将两个字节转换为16位值的最有效方法
- 为什么 Linux 的 IPv4 地址占用 16 个字节而不是 4 个字节