ARM-为什么gcc为单个字符分配12个字节?
我有以下代码:ARM-为什么gcc为单个字符分配12个字节?,c,assembly,stack,arm,C,Assembly,Stack,Arm,我有以下代码: int main() { volatile char a; return 0; } 当我使用arm linux gnueabihf gcc-o align.txt-O0-S align.c对其进行反汇编时,我得到以下结果: push {r7} sub sp, sp, #12 ... 现在,我知道ARM EABI要求堆栈是8字节对齐的,这可以解释gcc分配的空间比a所需的单个字节多。然而,我认为它应该分配4个字节来为a和3个填充字节腾出空间 看起来它分配
int main()
{
volatile char a;
return 0;
}
当我使用arm linux gnueabihf gcc-o align.txt-O0-S align.c对其进行反汇编时,我得到以下结果:
push {r7}
sub sp, sp, #12
...
现在,我知道ARM EABI要求堆栈是8字节对齐的,这可以解释gcc分配的空间比a
所需的单个字节多。然而,我认为它应该分配4个字节来为a
和3个填充字节腾出空间
看起来它分配了4个字节来对齐推送的r7,然后再分配8个字节(1个用于a
,7个用于填充)。如果我定义一个9成员的字符数组,它将分配20个字节
为什么推R7需要自己的填充?在C/C++中,
< P>,在32/64位机器上,8位或16位的参数被作为32位参数传递(可能在64位机器上有64位)。然后,被调用函数只使用32位参数中较低的8位或16位。某些(或大多数)32/64位处理器没有或使用推送字节或推送短字符进行堆栈操作。如果使用快速调用API,则前几个参数将使用32位或64位寄存器示例汇编代码可能将堆栈与16字节边界对齐,也可能对局部变量进行默认分配,或者调试器使用堆栈 愚蠢的问题,暗中捅了一刀:如果你删除了“volatile”,并使用
a
,这样它就不会被编译掉,这是一样的吗?请注意,当你不启用优化时,gcc做了很多非常幼稚的事情。是的,你应该使用-O3
,然后更改返回0
到返回a代码>这样它就不会被优化了。您将看到分配了8个字节。@MarcusMüller是。我也尝试了Jester的建议,它只是编译成movsr0,#0
。gcc似乎变得更加智能化了,在上进行了优化。-Os
会发生什么?