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;
}
On my Ubuntu server 12.04.04 LTS I compile this program using
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
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".
But why does the stack pointer get decremented by 36 and not just 32?
bx lr
. You don't use any calculated values insum()
, so the entire routine maybe eliminated. You can not be compiling with any optimizations (or have not specified). A compiler can always reserve more than needed. – Pettitoessum()
toreturn x + y + z - z2;
andgcc
at-O3
converted it tomovs r0,#22
! Stack rationals (and any rationals in regards to code generation) depend on different compiler options. – Pettitoes