0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

冬至配饺子 来源:最后一个bug 作者:bug菌 2022-07-28 11:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在学校或者各种编程类书本上,基本上都会看到一句话:"函数是程序的基本组成单位",可以说理解函数对编程是非常重要的,与函数调用紧密结合的机制就是函数调用栈了,而栈有一个特别的属性就是栈的增长方向问题了,也发现一些多年编程经验的朋友对这一块都有点迷迷糊糊的。在阅读RTOS源码的时候也会经常看到栈的增长方向配置项目,那么今天就带大家了解一下栈的增长方向到底是咋回事。

1、栈的增长方向

首先我们要明确的是栈同样也是分布在我们的内存之中,而内存是通过地址来进行编排访问的,如下是堆栈的示意图:

poYBAGLiAHuAAbKkAABnWFxTtuQ560.png

对于堆栈而言原本并没有方向一说,只有入栈和出栈一说,程序中执行push指令则栈顶向上移动,执行pop指令则栈顶向下移动,其仅仅只是一种先进后出的数据结构,增长方向都是从栈底向栈顶方向移动,即分配数据的过程。

而我们平时所说的栈的增长方向又是怎么回事呢?

为了在内存中分配一段内存给堆栈,我们必须要区分堆栈相对于内存的地址而言的方向性,通常栈顶增长的方向是从内存的低地址向高地址变化,我们则称为向上增长;反之则向下增长。

所谓"水往高处流,即向上增长",这样应该就很好记忆了。

2、有什么用?

当了解处理器中栈指针的增长方向以后,我们在debug程序的时候才能真正的把控程序的运行过程。

在移植RTOS的过程中我们都需要对每个任务的堆栈分配一个合适的连续内存区域来使用,此时初始状态堆栈指针指向什么位置就跟堆栈的增长方向密切相关,有过RTOS移植经验的朋友应该都有在RTOS配置项中关注过这块的选择。

RTOS在任务初始化的时候,其堆栈指针应该指向其栈底位置,那么对于堆栈向上增长,任务初始化的时候我们需要把堆栈指针设置在所分配内存的低地址内存处,反之则设置到高地址处。

poYBAGLiAKKAFXH2AABy3437hcQ779.png

设置好以后,其在堆栈分配的过程中才会朝着所分配的内存区域中,否则就会堆栈反向自爆,导致程序异常;如果你的堆栈分配不合理,同样了解堆栈变化方向后也变得有迹可循。

同样在裸机程序中也需要了解一下处理器的堆栈变化方向,从而用来排查一些堆栈溢出所导致的程序异常问题。

3、用C语言如何判断?

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

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

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

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

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

基于这样的思想,这里bug菌写一个判断堆栈增长方向的demo供大家参考:

poYBAGLiAMmAOSP7AAD6dMwwGvQ386.pngpoYBAGLiAM2ABykAAACdf-nzKFc394.png

可以拿去试一试,看看你的芯片堆栈咋变化的~


审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    20148

    浏览量

    246957
  • 芯片
    +关注

    关注

    462

    文章

    53530

    浏览量

    458861
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144558
  • RTOS
    +关注

    关注

    25

    文章

    862

    浏览量

    122572
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Stack到底用来干嘛的

    我们在函数的局部变量、数组这些不能超过1K(含嵌套的函数),否则程序就会崩溃进入hardfaul。 除了这些局部变量以外,还有一些实时操作系统的现场保护、返回地址都是存储在里面。 还有一点题外话,就是增长方向是从高地址到低
    发表于 12-01 08:04

    C语言程序的结构

    ,87LPC764有4KB的Flash ROM,而笔者的程序量只有2KB多点,因而第一个想法是改用C语言作为主要的开发语言,应该不至于导致代码空间不够用。其次,考虑到需要定时功能的模块(或称任务,以下统称任务
    发表于 11-26 08:12

    C语言的常量介绍

    、-13; 实型常量:13.33、-24.4; 字符常量:‘a’、‘M’ 字符串常量:”I love china!” 在C语言中,可以一个标识符来表示一个常量,称之为符号常量。符号常量在使用之前必须先
    发表于 11-24 07:12

    C语言特性

    数据,实现对设备的精准控制,同时降低功耗,延长设备的使用寿命。 2、可移植性:跨平台的通行证 C 语言具有良好的可移植性,这意味着 C 语言
    发表于 11-24 07:01

    C语言在嵌入式开发中的应用

    发动机的最佳性能和燃油经济性。C 语言的高效性和对硬件的直接操作能力,使得它能够满足 ECU 对实时性和精确性的严格要求。据统计,全球超过 80% 的汽车 ECU 软件都是 C
    发表于 11-21 08:09

    2025年最佳的嵌入式编程语言有哪些

    语言有哪些?今天我们将讨论这些语言CC++、Rust、Python和生成式AI提示;以及它们在当今的现代系统中的使用方式。资料来源:T
    的头像 发表于 11-14 10:27 884次阅读
    2025年最佳的嵌入式编程<b class='flag-5'>语言</b>有哪些<b class='flag-5'>呢</b>?

    C语言和单片机C语言有什么差异

    单片机c语言相对于普通C语言增加了一些基本的指令,还有变量的赋值是16进制,当然单片机c语言只牵
    发表于 11-14 07:55

    C语言的printf基本用法介绍

    个简单的例子: printf(\"C语言\"); 这个语句可以在屏幕上显示“C语言”,与puts(\"C
    发表于 11-12 07:04

    怎么判断我现在用的是外部时钟还是内部时钟

    在用i2c或者其他通讯协议的时候,都要去cubemx移植代码过来,我怎么判断我现在用的是外部时钟还是内部时钟
    发表于 09-28 15:21

    基于LabVIEW的鼠标滑动方向检测教程

    本篇教程源于一位客户的真实需求,需要LabVIEW能够检测到鼠标滑动的方向,然后通过判断滑动方向处理后续的功能。
    的头像 发表于 07-30 13:51 565次阅读
    基于LabVIEW的鼠标滑动<b class='flag-5'>方向</b>检测教程

    深入理解C语言C语言循环控制

    C语言编程中,循环结构是至关重要的,它可以让程序重复执行特定的代码块,从而提高编程效率。然而,为了避免程序进入无限循环,C语言提供了多种循环控制语句,如break、continue和
    的头像 发表于 04-29 18:49 1728次阅读
    深入理解<b class='flag-5'>C</b><b class='flag-5'>语言</b>:<b class='flag-5'>C</b><b class='flag-5'>语言</b>循环控制

    C语言的历史及程序介绍

    电子发烧友网站提供《C语言的历史及程序介绍.pdf》资料免费下载
    发表于 04-09 16:10 0次下载

    51单片机C语言学习笔记

    c51语言快速入门
    发表于 03-24 14:04 3次下载

    MATLAB或者C语言开发FPGA有什么问题吗

    最近有个项目领导要求MATLAB开发FPGA,有大佬MATLAB或者C语言开发FPGA的吗,有没有什么问题,需要注意什么问题吗
    发表于 01-26 09:57

    EE-33:C语言对ADSP-21xx定时器进行编程

    电子发烧友网站提供《EE-33:C语言对ADSP-21xx定时器进行编程.pdf》资料免费下载
    发表于 01-15 15:46 0次下载
    EE-33:<b class='flag-5'>用</b><b class='flag-5'>C</b><b class='flag-5'>语言</b>对ADSP-21xx定时器进行编程