gpt4 book ai didi

c - 了解堆栈分配和对齐

转载 作者:太空狗 更新时间:2023-10-29 17:11:33 25 4
gpt4 key购买 nike

我正在尝试了解堆栈对齐的工作原理,如 what is "stack alignment"? 中所述。但我很难得到一个小例子来证明上述行为。我正在检查函数 foo 的堆栈分配:

void foo() {
int a = 0;
char b[16];
b[0] = 'a';
}

我用 gcc -ggdb example.c -o example.out 编译了源文件(即没有任何编译器标志)并且 gdb 的汇编转储读取:

(gdb) disassemble foo
Dump of assembler code for function foo:
0x08048394 <+0>: push %ebp
0x08048395 <+1>: mov %esp,%ebp
0x08048397 <+3>: sub $0x20,%esp
0x0804839a <+6>: movl $0x0,-0x4(%ebp)
0x080483a1 <+13>: movb $0x61,-0x14(%ebp)
0x080483a5 <+17>: leave
0x080483a6 <+18>: ret
End of assembler dump.

我的堆栈是按 16 字节的 block 分配的(我用其他几个测试验证了这一点)。根据这里的汇编程序转储,已经分配了 32 个字节,因为 (16 < 4+16 < 32),但是我希望在前 16 个字节上分配整数 'a',然后在接下来的 16 个字节上分配字符数组(中间留有 12 个字节的空间)。但似乎整数和字符数组都被分配了一个 20 字节的连续 block ,根据我上面提到的讨论,这是低效的。有人可以解释一下我在这里缺少什么吗?

编辑:我得出的结论是,我的堆栈是以 16 字节为单位分配的,程序如下:

void foo() {
char a[1];
}

以及相应的汇编程序转储:

(gdb) disassemble foo
Dump of assembler code for function foo:
0x08048394 <+0>: push %ebp
0x08048395 <+1>: mov %esp,%ebp
0x08048397 <+3>: sub $0x10,%esp
0x0804839a <+6>: leave
0x0804839b <+7>: ret
End of assembler dump.

您可以看到在堆栈上为大小为 1 的字符数组分配了 16 个字节(只需要 1 个字节)。我可以将数组的大小增加到 16,汇编程序转储保持不变,但是当它是 17 时,它会在堆栈上分配 32 个字节。我运行了很多这样的样本,结果都是一样的;堆栈内存以 16 字节的 block 分配。 Stack allocation, padding, and alignment 中讨论了类似的主题但我更想知道为什么对齐在我的示例中不起作用。

最佳答案

我认为您忽略了一个事实,即不需要所有堆栈变量都单独对齐到 16 字节边界。

关于c - 了解堆栈分配和对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4817473/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com