我的堆栈是向上而不是向下增长吗?

so.*_*red 5 c gcc

据我所知,堆栈假设向下增长.

我试着运行这段代码:

#include<stdio.h>

void func(char* a1, int a2, int a3) {

    char b1[10];
    int b2;
    int b3;

    printf("a3 address is: %p\n", &a3);
    printf("a2 address is: %p\n", &a2);
    printf("a1 address is: %p\n", &a1);
    printf("-----------------------\n");
    printf("b1 address is: %p\n", &b1);
    printf("b2 address is: %p\n", &b2);
    printf("b3 address is: %p\n", &b3);
}


int main() {
    func("string",2,3);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果不像我预期的那样:

a3 address is: 0x7fff68473190
a2 address is: 0x7fff68473194
a1 address is: 0x7fff68473198
-----------------------
b1 address is: 0x7fff684731b0
b2 address is: 0x7fff684731a8
b3 address is: 0x7fff684731ac
Run Code Online (Sandbox Code Playgroud)

我不指望b1,b2,b3在我宣布他们以同样的方式进行排序.我知道编译器可能会更改该顺序以启用优化和对齐,但为什么堆栈似乎朝着高地址而不是低地址增长?

NPE*_*NPE 4

tl;dr 使用您问题中的代码,我们无法判断。

局部变量在堆栈中出现的顺序由编译器决定。它可能会重新排序,或者甚至可能不为某些变量分配堆栈空间(因为它们被优化掉了,或者被分配给了寄存器)。

函数参数被压入堆栈的方式——如果有的话!-- 由您的平台的ABI决定。%edi在我的例子(x86-64)中,三个参数在寄存器( 、%esi和)中传递%edx

main:
        ...
        movl    $3, %edx
        movl    $2, %esi
        movl    $.LC7, %edi
        call    func
Run Code Online (Sandbox Code Playgroud)

为了编译采用a1a2和的地址的代码a3,编译器必须不遗余力地将三个寄存器的值存储在实际上是三个未命名的局部变量中:

func:
        ...
        movq    %rdi, -56(%rbp)
        movl    %esi, -60(%rbp)
        movl    %edx, -64(%rbp)
Run Code Online (Sandbox Code Playgroud)

总之,您问题中的代码不足以断定堆栈的增长方式。

幸运的是,我们先验地知道这种事情,或者可以使用不同的代码来弄清楚:大多数现代系统中堆栈增长的方向是什么?