如何理解栈的增长方向

1、概念

函数调用栈,简称栈。不管是函数的执行还是函数调用,栈都起着非常重要的作用

  • 保存函数的局部变量
  • 向被调用函数传递参数
  • 返回函数的返回值
  • 保存函数的返回地址。返回地址是指从被调用函数返回后调用者应该继续执行的指令地址

该文章会帮你很好的了解函数栈——x86_64栈和函数调用

每个函数在执行过程中都需要使用一块栈内存用来保存上述这些值,我们称这块栈内存为某函数的栈帧(stack frame)。当发生函数调用时,因为调用者还没有执行完,其栈内存中保存的数据还有用,所以被调用函数不能覆盖调用者的栈帧,只能把被调用函数的栈帧“push”到栈上,等被调函数执行完成后再把其栈帧从栈上“pop”出去,这样,栈的大小就会随函数调用层级的增加而生长,随函数的返回而缩小。

栈的生长和收缩都是自动的,由编译器插入的代码自动完成(通常可以通过汇编代码看到 push、pop 相关操作),因此位于栈内存中的函数局部变量所使用的内存随函数的调用而分配,随函数的返回而自动释放,所以程序员不管是使用有垃圾回收还是没有垃圾回收的高级编程语言都不需要自己释放局部变量所使用的内存,这一点与堆上分配的内存截然不同。

栈顶和栈底共同决定了一个栈帧

  • 栈底:在未涉及函数调用时,栈底是不变的。通过栈底去访问栈中的变量
  • 栈顶:随着入栈、出栈动作,栈顶是动态变化的

栈的生长方向,一定是由 栈底 -> 栈顶。只是说,栈底可能是低地址,也可能高地址

2、测试程序

用代码判断栈的增长方向,代码转载自文章 用代码判断栈增长方向

/*
 * test.c
 */
 
#include <stdio.h>
#include <stddef.h>

typedef enum {Upward, Downward} Stack_Dir_t;

Stack_Dir_t detect_stack_dir(char * p) {
    char local = 0;
    if (p) {
        return &local > p ? Upward : Downward;
    } else {
        return detect_stack_dir(&local);
    }
}

int main() {
    if (detect_stack_dir(NULL) == Upward)
        printf("Stack Growth Upward!\n");
    else
        printf("Stack Growth Downward!\n");

    return 0;
}

运行结果:

cfp@cfp-virtual-machine:~/Desktop$ gcc test.c -o test
cfp@cfp-virtual-machine:~/Desktop$ ./test 
Stack Growth Downward!

表明,栈的生长方向,为 高地址 -> 低地址,栈底是 高地址

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值