为什么GCC在堆栈上分配的空间超出了对齐所需的空间? [英] Why does GCC allocate more space than necessary on the stack, beyond what's needed for alignment?
问题描述
我正在读一本教科书,其中显示了基于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 ,其中
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.
我的疯狂猜测是,直到之后它已经确定需要超过8个字节的空间(因此需要24个字节),GCC才会对其进行优化.希望这个好的MCVE可以让GCC开发人员找到一个可以轻松修复的bug.
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.
您是正确的,按照x86-64 System V ABI的要求,分配8个字节足以使char buf[8]
和在call
之前将RSP对齐16. a href ="https://stackoverflow.com/q/49391001">为什么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屋!