当前位置: 首页 > news >正文

在STM32嵌入式中C/C++语言对栈空间的使用

像STM32这样的微控制器在进入main函数之前需要对栈进行初始化。可以说栈是C语言运行时的必要条件。我们知道栈实际上是一块内存空间,那么这块空间都用来存储什么呢?有什么办法能够优化栈空间的使用?

栈空间内容

栈空间保存的内容

栈是一个先入后出的数据结构,是用来保存数据用的,在C语言中,需要提供一块栈空间用于C语言的运行,而且在STM32的寄存器中有个专门的寄存器SP指向当前的栈顶地址。那么C语言都用栈空间保存什么?

C语言使用栈空间存储一些函数运行时需要的内容,包括:

  1. 函数的返回地址,当函数执行完毕,需要返回原函数时,就会将此地址出栈并赋值给PC寄存器,从而返回原函数继续执行。
  2. 保存必要的寄存器内容。当函数跳转时,或者进入中断子函数时,需要对原函数所使用的寄存器内容进行保存(不一定是对所有的寄存器进行保存,这个由编译器决定,只保存在子函数中需要用到的寄存器,比如子函数中用到了寄存器R4和R5,那么就需要在进入子函数前先进原函数使用的R4和R5寄存器内容压入栈中),当子函数执行完,重新返回原函数时,能够将栈空间里保存的内容重新恢复到寄存器中,继续执行原函数的内容。
  3. 结构体、数组、联合体,这些类型的局部变量,还有c++里的类,这些类型的局部变量一般不会放在寄存器中,而是在栈空间中。
    4 整型或者浮点型的局部变量,也有可能分配到栈空间上。一般整型和浮点型会分配到寄存器中,这样其读写速度会比较快,但是当变量过多,造成寄存器不够用的时候,就会将一部分整型或者浮点型的局部变量分配到栈空间中。
    5 一些函数的参数也可能通过栈进行传递,这和参数的类型、大小和顺序有关,比如当传递的参数个数超过5个时,就会将部分参数通过栈进行传递。

有一些要注意:

  1. 可变长度的数组是分配到堆上的,不在栈上。
  2. 当开启编译器的优化时,有些优化策略会自动的引入新的临时变量来保存一些中间结果,编译器会先尝试将这些临时变量分配给寄存器,如果寄存器不够时,就会将其放在栈上。
优化栈空间的使用

栈空间一般都是在RAM中的,而在微控制器中,RAM一般都比较小,如果栈空间过大的话,能够使用的RAM就会减少,因此有时希望能够减小栈空间使用,其方法如下:

  1. 减少函数中局部变量的个数。
  2. 避免在局部变量中使用大数组或者大的结构体,因为这些变量会在栈上占用比较大的空间。
    3 避免使用递归算法,因为递归函数是函数的嵌套,每次嵌套都需要将一部分寄存器的值保存到栈中,增加了栈的使用。
    4 使用C语言的块作用域,只在需要的地方声明变量,这样当程序退出当前块的时候,就会回收这个块内局部变量,能够重复利用栈的空间。

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Matlab Git管理
  • shell 条件语句
  • 不同类型的指针变量进行++操作的效果
  • allure_pytest:AttributeError: ‘str‘ object has no attribute ‘iter_parents‘
  • MongoDB文档整理
  • JavaScript:节流与防抖
  • 主页目录导航
  • Unity XR Interaction Toolkit(VR、AR交互工具包)记录安装到开发的流程,以及遇到的常见问题(一)!
  • 如何将PDF转换成可以直接编辑的CAD图纸?
  • 前端下载文件流 出现乱码 解决方案
  • Random,ThreadLocalRandom,SecureRandom有什么区别
  • 【STM32 HAL库】全双工I2S+双缓冲DMA的使用
  • 科研绘图系列:R语言雨云图(Raincloud plot)
  • 【云原生】Prometheus 服务自动发现使用详解
  • Linux入门攻坚——28、php、mysql基础
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • ECS应用管理最佳实践
  • HTTP--网络协议分层,http历史(二)
  • java8-模拟hadoop
  • PaddlePaddle-GitHub的正确打开姿势
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Python学习笔记 字符串拼接
  • Rancher-k8s加速安装文档
  • SAP云平台里Global Account和Sub Account的关系
  • sublime配置文件
  • 阿里云前端周刊 - 第 26 期
  • 高程读书笔记 第六章 面向对象程序设计
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 经典排序算法及其 Java 实现
  • 开源地图数据可视化库——mapnik
  • 面试遇到的一些题
  • 前端工程化(Gulp、Webpack)-webpack
  • 设计模式 开闭原则
  • 智能网联汽车信息安全
  • 数据可视化之下发图实践
  • ​Java并发新构件之Exchanger
  • #Datawhale AI夏令营第4期#多模态大模型复盘
  • #Linux(Source Insight安装及工程建立)
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (12)Hive调优——count distinct去重优化
  • (day 12)JavaScript学习笔记(数组3)
  • (pojstep1.1.2)2654(直叙式模拟)
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (二)windows配置JDK环境
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转) 深度模型优化性能 调参
  • ./configure,make,make install的作用(转)
  • .form文件_SSM框架文件上传篇
  • .net core 的缓存方案
  • .NET IoC 容器(三)Autofac
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .net6+aspose.words导出word并转pdf
  • .NET是什么