打印
[其它应用]

栈的增长方向,用C语言如何判断?

[复制链接]
2346|41
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我们在学校或者各种编程类书本上,通常都会看到一句话:“函数是程序的基本组成单位”。可以说,理解函数对编程是非常重要的,与函数调用紧密结合的机制就是函数调用栈了。而栈有一个特别的属性,那就是栈的增长方向问题了。
最近我发现一些多年编程经验的朋友对这一块也是迷迷糊糊的,在阅读RTOS源码的时候,也会经常看到栈的增长方向配置项目,那么今天就带大家了解一下栈的增长方向到底是咋回事。
1
栈的增长方向
首先,我们要明确的是栈同样也是分布在我们的内存之中,而内存是通过地址来进行编排访问的,如下是堆栈的示意图:
对于堆栈而言原本并没有方向一说,只有入栈和出栈一说,程序中执行push指令则栈顶向上移动,执行pop指令则栈顶向下移动,其仅仅只是一种先进后出的数据结构,增长方向都是从栈底向栈顶方向移动,即分配数据的过程。
而我们平时所说的栈的增长方向又是怎么回事呢?
为了在内存中分配一段内存给堆栈,我们必须要区分堆栈相对于内存的地址而言的方向性,通常栈顶增长的方向是从内存的低地址向高地址变化,我们则称为向上增长;反之则向下增长。
所谓“水往高处流,即向上增长”,这样应该就很好**了。
2
有什么用?
当了解处理器中栈指针的增长方向以后,我们在debug程序的时候才能真正的把控程序的运行过程。
在移植RTOS的过程中我们都需要对每个任务的堆栈分配一个合适的连续内存区域来使用,此时初始状态堆栈指针指向什么位置就跟堆栈的增长方向密切相关,有过RTOS移植经验的朋友应该都有在RTOS配置项中关注过这块的选择。
RTOS在任务初始化的时候,其堆栈指针应该指向其栈底位置,那么对于堆栈向上增长,任务初始化的时候我们需要把堆栈指针设置在所分配内存的低地址内存处,反之则设置到高地址处。

使用特权

评论回复
沙发
两只袜子|  楼主 | 2023-11-1 15:21 | 只看该作者
3

用C语言如何判断?

要了解一个CPU的堆栈的变换方向,一方面就是查询相应的芯片参考手册,另外一方面就是实际测试了。

毕竟堆栈也就是内存,自然就可以通过堆栈的分配过程取出所分配的内存地址来比较判断,而C语言可以方便的访问内存,也就比较容易判断当前处理器中堆栈指针的增长方向了。

那还不简单,直接在函数内部先后定义两个局部变量,直接比较两个变量的地址大小不就搞定了吗?其实这种方式是依赖于编译器实现的,毕竟哪个变量先进行内存申请,并没有太大的影响。

那么,是否有一种方法不依赖于编译器实现呢?

必须有的,那就是函数调用栈了,因为先调用的函数必然首先入栈。

基于这样的思想,这里bug菌写一个判断堆栈增长方向的demo供大家参考:
1#include <stdio.h>
2#include <stdlib.h>
3
4#define STACK_UP (0)
5#define STACK_DN (1)
6
7/***************************************
8@ Function: find_stack_direction
9@ Author  : bug man
10@ Note    : (公众号:最后一个bug)
11****************************************/
12int find_stack_direction(int* ptr)
13{
14    int  Val = 0;
15
16    printf("Last stack Addr : %p\n",ptr);
17    printf("Now  stack Addr : %p\n",&Val);
18
19    if(ptr > &Val)
20    {
21        return STACK_DN;
22    }
23
24    return STACK_UP;
25}
26/***************************************
27@ Function: main
28@ Author  : bug man
29@ Note    : (公众号:最后一个bug)
30****************************************/
31int main(int argc, char *argv[]) {
32    int  Val = 0;
33
34    printf("stack direction : %d\n",find_stack_direction(&Val));
35    return 0;
36}
感兴趣的小伙伴可以拿去试一试,看看你的芯片堆栈咋变化的~
来源:最后一个bug

使用特权

评论回复
板凳
LOVEEVER| | 2023-11-2 08:37 | 只看该作者
栈顶增长的方向是从内存的低地址向高地址变化,我们则称为向上增长;反之则向下增长。

使用特权

评论回复
地板
星辰大海不退缩| | 2023-11-2 08:45 | 只看该作者
我记得堆栈只有入栈和出栈一说

使用特权

评论回复
5
OKAKAKO| | 2023-11-2 09:06 | 只看该作者
与函数调用紧密结合的机制就是函数调用栈了,堆栈的使用应该是不同的

使用特权

评论回复
6
小夏天的大西瓜| | 2023-11-2 09:23 | 只看该作者
栈就是PUSH的一段空间内存

使用特权

评论回复
7
minzisc| | 2023-11-7 16:07 | 只看该作者
可以通过栈指针的方式来判断栈的增长方向。

使用特权

评论回复
8
houjiakai| | 2023-11-7 17:12 | 只看该作者
如果栈增长方向是从低地址到高地址,那么栈指针会指向下一个被调用的函数的栈顶位置。反之,如果栈增长方向是从高地址到低地址,那么栈指针会指向上一个被调用的函数的栈底位置。

使用特权

评论回复
9
uptown| | 2023-11-7 19:41 | 只看该作者
内存通常是从高位地址向低位地址增长的,而栈是一种后进先出(LIFO)的数据结构,所以新的栈空间会被分配在旧的栈空间的下面。

使用特权

评论回复
10
pentruman| | 2023-11-7 20:03 | 只看该作者
在C语言中,栈的增长方向通常是向下的

使用特权

评论回复
11
i1mcu| | 2023-11-7 21:48 | 只看该作者
不能直接从 C 语言中判断栈的增长方向。

使用特权

评论回复
12
pl202| | 2023-11-7 22:14 | 只看该作者
大多数系统会选择向下(即低地址)增长

使用特权

评论回复
13
qiufengsd| | 2023-11-7 22:24 | 只看该作者
栈空间的增长是从高地址向低地址方向。

使用特权

评论回复
14
eefas| | 2023-11-7 22:43 | 只看该作者
新的栈空间会被分配在旧的栈空间的下面。

使用特权

评论回复
15
maqianqu| | 2023-11-7 22:53 | 只看该作者
增长方向是从高地址向低地址增长。

使用特权

评论回复
16
51xlf| | 2023-11-8 09:48 | 只看该作者
随着函数的调用,栈空间会不断增加。通过分析程序中的函数调用关系,可以判断栈的增长方向。

使用特权

评论回复
17
mmbs| | 2023-11-8 10:04 | 只看该作者
在C语言中,可以使用指针的加减操作来判断栈的增长方向。

使用特权

评论回复
18
gygp| | 2023-11-8 11:07 | 只看该作者
栈的增长方向通常是由操作系统和具体的编译器决定的,这不是由程序员直接控制的

使用特权

评论回复
19
sesefadou| | 2023-11-8 11:16 | 只看该作者
通过分析程序的运行过程,观察栈空间的变化。

使用特权

评论回复
20
mmbs| | 2023-11-8 11:25 | 只看该作者
栈空间的增长方向与函数调用密切相关。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1884

主题

6474

帖子

8

粉丝