为什么在这个例子中gcc没有为局部变量分配空间? [重复]

问题描述 投票:0回答:1

这是我用

gcc
编译的C代码 -

#include <stdio.h>
#include <stdlib.h>

int sum(int arr[20]) {
    int s = 0;
    for (int i = 0; i < 20; i++)
        s += arr[i];
    return s;
}

int main(int argc, char **argv) {
    int arr[20] = {4, 5, 2, 12, 0, -23};
    printf("%d\n", sum(arr));
    return 0;
}

它生成的程序集 -

sum:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-24], rdi
        mov     DWORD PTR [rbp-4], 0
        mov     DWORD PTR [rbp-8], 0
        jmp     .L2
.L3:
        mov     eax, DWORD PTR [rbp-8]
        cdqe
        lea     rdx, [0+rax*4]
        mov     rax, QWORD PTR [rbp-24]
        add     rax, rdx
        mov     eax, DWORD PTR [rax]
        add     DWORD PTR [rbp-4], eax
        add     DWORD PTR [rbp-8], 1
.L2:
        cmp     DWORD PTR [rbp-8], 19
        jle     .L3
        mov     eax, DWORD PTR [rbp-4]
        pop     rbp
        ret
.LC0:
        .string "%d\n"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 96
        mov     DWORD PTR [rbp-84], edi
        mov     QWORD PTR [rbp-96], rsi
        pxor    xmm0, xmm0
        movaps  XMMWORD PTR [rbp-80], xmm0
        movaps  XMMWORD PTR [rbp-64], xmm0
        movaps  XMMWORD PTR [rbp-48], xmm0
        movaps  XMMWORD PTR [rbp-32], xmm0
        movaps  XMMWORD PTR [rbp-16], xmm0
        mov     DWORD PTR [rbp-80], 4
        mov     DWORD PTR [rbp-76], 5
        mov     DWORD PTR [rbp-72], 2
        mov     DWORD PTR [rbp-68], 12
        mov     DWORD PTR [rbp-60], -23
        lea     rax, [rbp-80]
        mov     rdi, rax
        call    sum
        mov     esi, eax
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 0
        leave
        ret

我主要关心的是

sum
函数。当我们压入旧的基指针值并将堆栈指针的当前值移入基指针后,
rbp
标记了堆栈的顶部。因此,从中减去的任何数量都意味着堆栈中存在未分配的空间。为什么
gcc
在未分配的空间中写入?为什么它不像
main
函数那样首先通过从堆栈指针中减去来腾出空间?

我希望所有函数首先为其局部变量腾出空间。但在这种情况下却没有

assembly stack x86-64 calling-convention red-zone
1个回答
-2
投票

因为gcc使用基指针(rbp)直接访问局部变量,而不需要调整堆栈指针(rsp)。这种方法通常称为“帧指针”方法。它通常用于叶函数(不调用其他函数的函数)或小函数中,以减少开销并提高性能。

优化:GCC对sum函数进行了优化,对于小的局部变量直接使用栈帧,避免了不必要的栈指针调整。

空间分配:在需要更多空间的函数中(如 main),GCC 显式调整堆栈指针以分配足够的空间。

© www.soinside.com 2019 - 2024. All rights reserved.