C数组的反汇编给出了奇怪的结果

disassembly of C array gives weird results

int square() {
    char test[50];
}

以上代码产生

square():
        push    rbp
        mov     rbp, rsp

当我将代码稍微更改为

int square() {
    char test[150];
}

生成的程序集是

square():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 40

这仍然很奇怪,因为我不明白为什么它不为以前的创建分配。我是 运行 在 -O0 所以 gcc 没有优化它。为什么 gcc 为错误大小的数组创建代码?

int square() {
    char a[50];
    char b[50];
}
square():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 8

与 x86 类似

int square() {
    char a[500];
}

使用 -m32 编译得到:

square():
        push    ebp
        mov     ebp, esp
        sub     esp, 512

这额外的 12 个字节来自哪里?为什么 -m32 有一个用于 char test[50] 的子指令,但 x86_64 没有?

GCC 在变量堆栈指针下方使用 x86-64 System V ABI 的 128 字节 Red Zone,仅在不够用时保留一些额外堆栈 space

对于最后一个示例,GCC subs 512 保持堆栈(和数组)对齐。

i386 System V ABI 没有红色区域,因此它必须为整个阵列保留 space(就此而言,Windows x64 也没有)。