我的堆栈是向上增长而不是向下增长吗? [复制]

Posted

技术标签:

【中文标题】我的堆栈是向上增长而不是向下增长吗? [复制]【英文标题】:Does my stack grow upward instead of downward? [duplicate] 【发布时间】:2015-02-21 16:03:54 【问题描述】:

据我所知,堆栈应该向下增长。

我试图运行这段代码:

#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;

结果并不如我所料:

a3 address is: 0x7fff68473190
a2 address is: 0x7fff68473194
a1 address is: 0x7fff68473198
-----------------------
b1 address is: 0x7fff684731b0
b2 address is: 0x7fff684731a8
b3 address is: 0x7fff684731ac

我不希望 b1,b2,b3 以我声明它们的相同方式订购。我知道编译器可能会更改该顺序以启用优化和对齐,但为什么看起来堆栈似乎向高地址而不是低地址增长?

【问题讨论】:

您正在比较单个堆栈帧中的变量,而不是单个堆栈帧... 【参考方案1】:

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

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

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

main:
        ...
        movl    $3, %edx
        movl    $2, %esi
        movl    $.LC7, %edi
        call    func

为了编译采用a1a2a3 地址的代码,编译器必须竭尽全力将三个寄存器的值存储在实际上是三个未命名的本地变量:

func:
        ...
        movq    %rdi, -56(%rbp)
        movl    %esi, -60(%rbp)
        movl    %edx, -64(%rbp)

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

幸运的是,我们先验地知道这种事情,或者可以使用不同的代码来解决它:What is the direction of stack growth in most modern systems?

【讨论】:

以上是关于我的堆栈是向上增长而不是向下增长吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

堆栈是向上还是向下增长

为啥堆栈不向上增长(为了安全)?

为啥堆栈通常会向下增长?

真正的内存结构是啥? [复制]

堆栈内存有限制吗?

鼠标悬停更改图像位置和大小