Why is the stack pointer moved down 4 bytes greater than the stack frame size when compiling with arm-linux-gnueabi-gcc?

StackOverflow https://stackoverflow.com/questions/22279911

Question

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?

Was it helpful?

Solution

Procedure call standard for ARM requires 8 byte alignment.

5.2.1.2 Stack constraints at a public interface

The stack must also conform to the following constraint at a public interface:

  • SP mod 8 = 0. The stack must be double-word aligned.

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.)

You can use -fomit-frame-pointer to skip pushing r7 then gcc should leave the stack depth at 32.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top