gpt4 book ai didi

c - 堆栈分配、填充和对齐

转载 作者:太空狗 更新时间:2023-10-29 16:19:28 25 4
gpt4 key购买 nike

我一直在努力更深入地了解编译器如何生成机器代码,更具体地说,GCC 如何处理堆栈。在这样做的过程中,我一直在编写简单的 C 程序,将它们编译成汇编,并尽我最大的努力来理解结果。这是一个简单的程序及其生成的输出:

asmtest.c:

void main() {
char buffer[5];
}

asmtest.s:

pushl   %ebp
movl %esp, %ebp
subl $24, %esp
leave
ret

令我困惑的是为什么要为堆栈分配 24 个字节。我知道由于处理器寻址内存的方式,堆栈必须以 4 为增量进行分配,但如果是这种情况,我们应该只将堆栈指针移动 8 个字节,而不是 24 个字节。作为引用,缓冲区为 17 bytes 产生一个堆栈指针移动 40 个字节,并且根本没有缓冲区移动堆栈指针 8。1 到 16 个字节之间的缓冲区移动 ESP 24 个字节。

现在假设 8 个字节是一个必要的常量(需要它做什么?),这意味着我们正在分配 16 个字节的 block 。为什么编译器会以这种方式对齐?我使用的是 x86_64 处理器,但即使是 64 位字也只需要 8 字节对齐。为什么会出现差异?

作为引用,我在运行 10.5 和 gcc 4.0.1 且未启用优化的 Mac 上编译它。

最佳答案

这是一个由 -mpreferred-stack-boundary=n 控制的 gcc 功能,其中编译器试图使堆栈上的项目与 2^n 对齐。如果将 n 更改为 2,它只会在堆栈上分配 8 个字节。 n 的默认值为 4 即它会尝试对齐到 16 字节边界。

为什么会有“默认”8字节然后24=8+16字节是因为堆栈已经包含8字节用于leaveret,所以编译后的代码必须首先将堆栈调整 8 个字节以使其对齐到 2^4=16。

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

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