为什么 GCC 在堆栈上分配的空间超出了所需的空间,超出了对齐所需的空间? [英] Why does GCC allocate more space than necessary on the stack, beyond what's needed for alignment?

查看:26
本文介绍了为什么 GCC 在堆栈上分配的空间超出了所需的空间,超出了对齐所需的空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一本教科书,其中展示了基于 C 代码的汇编代码:

I'm reading a textbook which shows assembly code based on C code:

C 代码:

void echo()
{
   char buf[8];
   otherFunction(buf);
}

汇编代码:

echo:
   subq $24, %rsp      //Allocate 24 bytes on stack, but why allocate 24 instead of 8 bytes?
   movq %rsp, %rdi     //Compute buf as %rsp
   call otherFunction  

我不明白为什么堆栈指针 %rsp 减少了 24 个字节.我只将 8 个字节的缓冲区分配为 char buf[8];,并且没有被调用者保存的寄存器压入堆栈,该指令不应该是

I don't understand why stack pointer %rsp is decremented by 24 bytes. I only assign 8 bytes' buffer as char buf[8];, and there no callee saved registers to push on stack, shouldn't the instruction be

subq $8, %rsp

推荐答案

分配额外的 16 字节堆栈空间是 GCC 遗漏的优化,偶尔会弹出.我不知道为什么会发生这种情况,但是可以使用 GCC10.1 -O3 重现.Clang 没有这样做,它只保留了 8 个字节(带有一个虚拟的 push).上 Godbolt 的,其中<代码> -fno堆叠保护器-fno馅饼是默认的,与许多 GNU/Linux 发行版中的 GCC 不同.

Allocating an extra 16 bytes of stack space is a GCC missed optimization that pops up occasionally. I don't know why it happens, but it's reproducible with GCC10.1 -O3. Clang doesn't do it, it just reserves 8 bytes (with a dummy push). Example on Godbolt, where -fno-stack-protector -fno-pie is the default, unlike GCC in many GNU/Linux distros.

即使 int buf;/foo(&buf) 也会导致过度分配.

Even int buf; / foo(&buf) results in over-allocation.

我疯狂的猜测是 GCC 不会优化某些东西,直到 之后它已经决定它需要超过 8 个字节的空间(因此需要 24 个).希望这个好的 MCVE 能让 GCC 开发人员找到修复那个错误的方法,如果它很容易修复的话.

My wild guess is that there's something GCC doesn't optimize away until after it's already decided it needs more than 8 bytes of space (and thus needs 24). Hopefully this good MCVE will let GCC devs find an fix that bug, if it's easily fixable.

请随意将此报告为 GCC missed-optimization 错误 (https://gcc.gnu.org/bugzilla/);我最近看了,但没有找到现有的.

Feel free to report this as a GCC missed-optimization bug (https://gcc.gnu.org/bugzilla/); I looked recently but didn't find an existing one.

您是正确的,分配 8 个字节足以 char buf[8] call,根据 x86-64 System V ABI 的要求(为什么 System V/AMD64 ABI 要求 16 字节堆栈对齐?).

You're correct that allocating 8 bytes would be enough for char buf[8] and re-align RSP by 16 before the call, as required by the x86-64 System V ABI (Why does System V / AMD64 ABI mandate a 16 byte stack alignment?).

GCC 不是试图保持 32 字节堆栈对齐或任何东西.-mpreferred-stack-boundary 的默认值是 ABI 允许的最小值,4 (2^4 = 16).

GCC is not trying to maintain 32-byte stack alignment or anything. The default for -mpreferred-stack-boundary is the minimum allowed by the ABI, 4 (2^4 = 16).

这篇关于为什么 GCC 在堆栈上分配的空间超出了所需的空间,超出了对齐所需的空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆