为什么堆栈指针向下移动比臂Linux的gnueabi-GCC编译时堆栈帧尺寸更大的4个字节? [英] Why is the stack pointer moved down 4 bytes greater than the stack frame size when compiling with arm-linux-gnueabi-gcc?
问题描述
使用下面的琐碎的C程序作为一个例子。主()使函数调用来概括传递4的整数。和()使用4本地人。
Using the trivial C program below as an example. main() makes a function call to sum passing in 4 integer. sum() uses 4 locals.
void sum(int a, int b, int c, int d);
void main(void)
{
sum(11, 12, 13, 14);
}
void sum(int a, int b, int c, int d)
{
int x;
int y;
int z;
int z2;
x = a;
y = b;
z = c;
z2 = d;
}
在我的Ubuntu服务器04年4月12日LTS我使用编译这个程序
On my Ubuntu server 12.04.04 LTS I compile this program using
ARM-Linux的gnueabi-GCC -S -mthumb func.c
arm-linux-gnueabi-gcc -S -mthumb func.c
sum:
@ args = 0, pretend = 0, frame = 32
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
push {r7}
sub sp, sp, #36 <=== why is this 36 and not 32 bytes?
add r7, sp, #0
str r0, [r7, #12]
str r1, [r7, #8]
str r2, [r7, #4]
str r3, [r7, #0] <- paramaters passed
ldr r3, [r7, #12]
str r3, [r7, #16] <- locals
ldr r3, [r7, #8]
str r3, [r7, #20]
ldr r3, [r7, #4]
str r3, [r7, #24]
ldr r3, [r7, #0]
str r3, [r7, #28]
add r7, r7, #36
mov sp, r7
pop {r7}
bx lr
看来,INT是一个4字节的每个。 4当地人和4个参数的功能,使共(4 * 4字节)+(4 * 4字节)= 32字节,这汇编输出框= 32。匹配
It appears that int's a 4 bytes each. 4 locals and 4 arguments for the function makes a total of (4 *4 bytes) + (4 * 4bytes) = 32 bytes and this matches the assembly output "frame = 32".
但为什么堆栈指针得到由36递减,并且不只是32?
But why does the stack pointer get decremented by 36 and not just 32?
推荐答案
有关ARM过程调用标准需要8字节对齐。
Procedure call standard for ARM requires 8 byte alignment.
在一个公共接口5.2.1.2堆栈限制
5.2.1.2 Stack constraints at a public interface
该协议栈还必须符合以下约束在一个公共接口:
The stack must also conform to the following constraint at a public interface:
- SPmod8 = 0的纸张都必须是双字对齐。
既然你是生产装配一切是默认输出,让您得到8字节对齐(我想这和gcc不添加。全球&LT;符号&GT;
指令生成集时,我想这说,即使一个静态函数是一个的公共接口的或GCC只对准每一个功能有8字节堆栈对齐静态函数。)
Since you are producing assembly everything is exported by default, so you get 8 byte alignment. (I tried this and gcc doesn't add .global <symbol>
directive to static functions when generating assembly. I guess this says even a static function is a public interface or gcc just aligns every function to have 8-byte stack alignment.)
<一个href=\"http://gcc.godbolt.org/#%7B%22version%22:3,%22filterAsm%22%3a%7B%22labels%22%3atrue,%22directives%22%3atrue,%22commentOnly%22%3atrue%7D,%22compilers%22%3a%5B%7B%22sourcez%22%3a%22G4ewlgJgBAzgrgWwBRgHYBcoEMA0U2YBGeBUAxiRlBAJQDcAUA6QlmkqJDQwN4NQDYiJAEYReEQCYJAZgkAWegwC+TTtHjJSufFWK7MFA9W59BxgB6NzpAJ7XBpAF4OBzyY36CLUALzZXKFs/KEJApxCycMkQiEZlIA=%22,%22compiler%22%3a%22/usr/bin/arm-linux-gnueabi-g++-4.6%22,%22options%22%3a%22-fomit-frame-pointer%20-mthumb%22%7D%5D%7D\"相对=nofollow>您可以使用 -fomit-frame-pointer的
跳过推 R7
然后海湾合作委员会应在32离开堆栈的深度。
You can use -fomit-frame-pointer
to skip pushing r7
then gcc should leave the stack depth at 32.
这篇关于为什么堆栈指针向下移动比臂Linux的gnueabi-GCC编译时堆栈帧尺寸更大的4个字节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!