为什么gcc在arm组件中分配更多堆栈?

时间:2017-03-06 03:27:07

标签: c gcc assembly arm

我正在尝试读取用ARM程序集编写的gcc的输出 以下输出对我来说很奇怪。

int succ (int *arr)
{
  return arr[0] + 1;
}

int main (int argc)
{
  int a[1] = { argc };
  return succ (a);
}

通过编译命令gcc -fno-inline -O2 -S,生成以下汇编程序。 我省略了关于succ的输出,因为它与我的问题无关(仅用于停止消除未使用的变量a)。

    .global main
    .type   main, %function
main:
    @ args = 0, pretend = 0, frame = 8
    @ frame_needed = 0, uses_anonymous_args = 0
    str     lr, [sp, #-4]!
    sub     sp, sp, #12
    add     r3, sp, #8
    str     r0, [r3, #-4]!
    mov     r0, r3
    bl      succ
    add     sp, sp, #12
    @ sp needed
    ldr     pc, [sp], #4
    .size   main, .-main

这个main函数似乎为本地数组a(sub sp,sp,#12)分配了3个字节。 但我的C程序只为a分配一个int元素 其他时间值似乎不使用堆栈。 为什么这个程序需要比我预期更多的堆栈量?

我的gcc版本是4.8.5。我在rasberry-pi 3中尝试过raspbian。

已更新
当我将数组a的长度修改为2(int a[2} = {argc, argc})时,音量不会改变(仅3个字节)。
对于长度为3(int a[3} = {argc, argc, argc}),堆栈中分配了5个字节。

我很好奇。

1 个答案:

答案 0 :(得分:0)

我前几天也看到过类似的东西。我怀疑它发生了什么,它已经把lr放在堆栈上。它需要将其与64位边界对齐,因此它需要在堆栈上再增加4个字节。然后它需要4个字节用于a,并且需要对齐,因此在堆栈上添加4个字节,没有意识到lr加上a是他们需要分配的全部。

我将不得不看看我是否能够以不同的方式重现它。