单片机堆栈分配

2023-05-16

Code:表示程序所占用 FLASH 的大小(FLASH)。
RO-data:即 Read Only-data,表示程序定义的常量,如 const 类型(FLASH)。
RW-data:即 Read Write-data,表示已被初始化的全局变量(SRAM)
ZI-data:即 Zero Init-data,表示未被初始化的全局变量(SRAM)

静态数据区(.data和.bss):保存全局变量和static 变量(包括static 全局和局部变量)。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(.data), 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss),程序结束后由系统释放。这些数据也是可读可写的,和stack、heap一样,被包含在sram中。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。
(freeRTOS为每个任务分配的栈空间使用的就是静态数据区,ucHeap[ portBYTE_ALIGNMENT ])
堆区(HEAP):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。在单片机的sram中的ZI-data中。由malloc 系列函数或new 操作符分配的内存。其生命周期由free 或delete 决定。在没有释放之前一直存在,直到程序结束。其特点是使用灵活,空间比较大,但容易出错。向上生长;
栈区(STACK):由编译器自动分配释放,在单片机的sram中的ZI-data。保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高,但空间大小有限。由高地址向低地址生长。

ZI-data的栈空间(Stack)及堆空间(Heap):

在C语言中,函数内部定义的局部变量属于栈空间,进入函数的时候向栈空间申请内存给局部变量,退出时释放局部变量,归还内存空间。而使用malloc动态分配的变量属于堆空间。
在程序中的栈空间和堆空间都是属于ZI-data区域的,这些空间都会被初始值化为0值。编译器给出的ZI-data占用的空间值中包含了堆栈的大小(经实际测试,若程序中完全没有使用malloc动态申请堆空间,编译器会优化,不把堆空间计算在内)。

内存分配方式有三种:

(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。 例如全局变量,static变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
栈内存 分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
空间分配

堆和栈的大小定义:

定义大小在startup_stm32f4xx.s

Stack_Size		EQU     0x400 //栈的大小为0X400
Heap_Size       EQU     0x800 //堆的大小为0X800

堆和栈地址:

通过MAP文件可知

 ucHeap                  0x20000764   Data        7150  heap_4.o(.bss)
 HEAP                    0x20002358   Section     2048  startup_stm32f103xb.o(HEAP)
 STACK                   0x20002b58   Section     1024  startup_stm32f103xb.o(STACK)

OS所使用的堆大小为 7150个字节,地址为0x20000764,在.bss(静态存储区)
程序堆大小为2048个字节,地址为0x20002358,在堆区
程序栈大小为1024个字节,地址为 0x20002b58,在栈区

静态占用最深的栈空间数量:

在Output目录下,有一个以工程文件命名的后缀为*.bulid_log.htm及*.htm文件其中*.build_log.htm是工程的构建过程日志,而*.htm是链接器生成的静态调用图文件。
在静态调用图文件中包含了整个工程各种函数之间互相调用的关系图,而且它还给出了静态占用最深的栈空间数量以及它对应的调用关系链。

Maximum Stack Usage = 3224 bytes + Unknown(Cycles, Untraceable Function Pointers)
Call chain for Maximum Stack Depth:
StartGPSTask ⇒ nmea_parse ⇒ nmea_parser_push ⇒ nmea_parser_real_push ⇒ nmea_parse_GPRMC ⇒ _nmea_parse_time ⇒ nmea_error ⇒ vsnprintf

该文件说明了本工程的静态栈空间最大占用3224字节(Maximum Stack Usage:3224bytes)
注意这里给出的空间只是静态的栈使用统计,链接器无法统计动态使用情况,例如链接器无法知道递归函数的递归深度。在本文件的后面还可查询到其它函数的调用情况及其它细节。

int a = 0; 
char *p1; //全局未初始化区
char s[512];//全局未初始化区
main()
{
	int b; 栈
	char s[] = "abc"; //栈
	char *p2; //栈
	char *p3 = "123456"; //123456\0在常量区,p3在栈上。
	static int c =0//全局(静态)初始化区
	p1 = (char *)malloc(10);  //堆
	p2 = (char *)malloc(20);  //堆
	strcpy(p1,   "123456");   //123456/0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。   
}

默认1K的栈,指的是call stack(函数调用使用的栈)。这个栈用来存放函数调用时所传递的参数(并非所有参数都通过栈传递),栈指针,return address,寄存器的备份,还有每层函数的local variable。
1K大多数情况都是够用的,如果用完可能会发生非法访问等错误。
可能会用完1K的情况:
某个被调用的函数申请了一个很大的local variable,比如直接在栈上开个大数组之类的;
还有就是递归调用,递归层数多了后很容易就用完1K。所以递归一般不要乱用。

扩展阅读:linux基础篇(二)——静态和动态链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机堆栈分配 的相关文章

  • 欧拉角pitch、yaw,roll的理解

    关于旋转永远是做游戏的难点和混乱点 我们知道表示一个旋转有多种方式 xff0c 简单的欧拉角 xff0c 复杂点的四元数 xff0c 再复杂点的矩阵 之前接触unity可以用四元数和欧拉角两种方式表示旋转 xff0c 最近一直研究虚幻引擎
  • Mac执行ruby命令提示 dyld: Library not loaded等类似问题解决方案

    说一下为啥会遇见这么个问题 xff0c 我在给一个xcode项目添加podfile的时候 xff0c 在终端执行了pod init命令 xff0c 随即给了我一个如下图的提示 xff08 报错信息一样的 xff0c 执行pod的命令早就被解
  • 编程题:多线程交替打印ABC

    要求创建3个线程 xff0c 分别打印ABC xff0c 共交替打印10次 span class token keyword public span span class token keyword class span span clas
  • Android App Bundle 自动打包原理

    Google推出Android App Bundle 已经有一段时间了 根据Google的政策说明 xff0c 预计2021年8月之后 xff0c 新发布的应用都必须使用Android App Bundle aab 来上架Google Pl
  • 【玩转Linux】Linux虚拟机设置固定IP

    Linux虚拟机Centos系统的ip总是变化 xff0c 如何固定下来 xff1f 尝试了好多方式 xff0c 终于找到一种最为简单的方法 文章目录 1 查看Centos的IP信息2 修改文件3 刷新网络配置 1 查看Centos的IP信
  • Docker安装MySQL数据库

    文章目录 一 简单方式二 挂载方式1 创建挂载目录2 启动容器 三 修改配置文件1 新建my cnf2 编辑my cnf3 查看是否生效 一 简单方式 span class token function docker span run sp
  • 解决Docker镜像拉取失败问题

    一 问题 Docker拉取mysql镜像 xff0c 发生报错 span class token function docker span pull mysql 8 0 22 报错信息 xff1a Error response from d
  • Docker安装RabbitMQ消息队列

    文章目录 1 启动容器2 连接访问 1 启动容器 span class token function docker span run name rabbitmq span class token punctuation span resta
  • 【玩转Linux】Linux安装宝塔面板

    文章目录 一 简介二 安装1 centos脚本安装2 浏览器访问 三 总结 一 简介 宝塔面板 xff0c 是安全高效的服务器运维面板 xff0c 一个提升运维效率的服务器管理软件 xff0c 支持一键LAMP LNMP 集群 监控 网站
  • 使用JDK的keytool工具生成JKS证书

    使用JDK的keytool工具生成JKS证书 文章目录 1 生成JKS证书2 查看JKS证书详细信息3 导出证书 1 生成JKS证书 keytool genkey alias jwt keyalg RSA keystore jwt jks
  • 【算法】二分查找

    算法 二分查找 题目 xff1a 请实现无重复数字的升序数组的二分查找 难度 xff1a 简单 代码 xff1a 二分查找 xff0c 又叫折半查找 xff0c 要求待查找的序列有序 每次取中间位置的值与待查关键字比较 xff0c 如果中间
  • 【算法】反转链表

    算法 反转链表 题目 xff1a 给定一个单链表的头结点pHead xff0c 长度为n xff0c 反转该链表后 xff0c 返回新链表的表头 难度 xff1a 简单 代码 xff1a span class token keyword c
  • 【算法】合并两个排序的链表

    算法 合并两个排序的链表 题目 xff1a 输入两个递增的链表 xff0c 单个链表的长度为n xff0c 合并这两个链表并使新链表中的节点仍然是递增排序的 难度 xff1a 简单 代码 xff1a span class token key
  • 【算法】判断链表中是否有环

    算法 判断链表中是否有环 题目 xff1a 判断给定的链表中是否有环 如果有环则返回true xff0c 否则返回false 难度 xff1a 简单 代码 xff1a span class token keyword public span
  • 教你快速高效接入SDK——手游聚合SDK的总体思路和架构

    U8SDK技术博客 xff1a http www uustory com xff0c 欢迎来坐坐 百度传课已经停运 xff0c 最新U8SDK视频教程已经转移至B站 xff1a U8SDK最新视频教程 题记 xff1a 很多做游戏开发的人
  • 【算法】删除链表的倒数第N个结点

    算法 删除链表的倒数第N个结点 题目 xff1a 给你一个链表 xff0c 删除链表的倒数第 n 个结点 xff0c 并且返回链表的头结点 难度 xff1a 中等 代码 xff1a span class token keyword publ
  • 阿里云智能编码插件Cosy,提升开发效率杠杠滴!

    文章目录 一 简介二 核心功能1 代码智能补全2 代码示例搜索 三 产品特性1 提升编码效率2 沉浸式开发3 低资源消耗4 隐私保护 四 快速开始1 安装IntelliJ IDEA插件2 测试代码智能补全3 测试代码示例搜索 五 总结 一
  • Alibaba Cloud Toolkit轻量部署插件,一键发布服务器

    文章目录 一 简介二 部署方式1 传统部署方式2 Cloud Toolkit部署方式 四 产品功能五 部署步骤1 安装插件2 添加主机3 Deploy to Host4 控制台5 服务器 六 服务器代码热部署七 Arthas诊断 一 简介
  • 新人一看就懂:Dubbo3 + Nacos的RPC远程调用框架demo

    文章目录 一 前言Feign和Dubbo到底有啥区别 xff0c 为啥大厂都爱用RPC框架 xff1f 二 简介三 dubbo api xff08 对外暴漏的接口 xff09 1 TestService接口 四 dubbo provider
  • Docker安装Kafka消息队列

    文章目录 1 安装zookeeper2 安装kafka3 安装kafka map xff08 可选 xff09 1 安装zookeeper span class token function docker span run span cla

随机推荐

  • 【Spring Boot实战与进阶】集成Kafka消息队列

    汇总目录链接 xff1a Spring Boot实战与进阶 学习目录 文章目录 一 简介二 集成Kafka消息队列1 引入依赖2 配置文件3 测试生产消息4 测试消费消息 一 简介 Kafka是由Apache软件基金会开发的一个开源流处理平
  • Hutool工具类之excel导入导出

    文章目录 1 导入excel2 导出excel 1 导入excel span class token class name ExcelReader span reader span class token operator 61 span
  • Docker安装RockerMQ消息队列

    文章目录 1 安装namesrv2 安装broker3 安装console xff08 可选 xff09 1 安装namesrv namesrv就类似于消息队列的注册中心 span class token function docker s
  • 【Spring Boot实战与进阶】集成RockerMQ消息队列

    汇总目录链接 xff1a Spring Boot实战与进阶 学习目录 文章目录 一 简介二 集成RockerMQ消息队列1 引入依赖2 配置文件3 测试生产消息4 测试消费消息 一 简介 RocketMQ 是阿里巴巴在2012年开源的分布式
  • linux下elasticsearch 安装、配置及示例

    简介 开始学es xff0c 我习惯边学边记 xff0c 总结出现的问题和解决方法 本文是在两台linux虚拟机下 xff0c 安装了三个节点 本次搭建es同时实践了两种模式 单机模式和分布式模式 条件允许的话 xff0c 可以在多台机器上
  • Java服务器热部署的实现原理

    今天发现早年在大象笔记中写的一篇笔记 xff0c 之前放在ijavaboy上的 xff0c 现在它已经访问不了了 前几天又有同事在讨论这个问题 这里拿来分享一下 在web应用开发或者游戏服务器开发的过程中 xff0c 我们时时刻刻都在使用热
  • win10打开热点提示:我们无法设置移动热点

    解决方案 xff1a 1 右键我的电脑 xff0c 打开管理 2 双击带有下载标记wi fi 适配器 xff0c 点击启用设备 xff0c 确认即可
  • Docker容器打包迁移

    有时在一个docker内部署的容器不想在其它服务器容器上重新部署 xff0c 再配置配置文件 这时直接将当前的容器打包然后直接部署到新的服务器上即可 xff0c 免了再配置一遍 1 将容器保存为镜像 先把容器停止运行不然会有问题 容器保存为
  • 四旋翼飞行器的原理研究和建模

    四旋翼飞行器的原理研究和建模 对四旋翼飞行器的工作原理进行了简单介绍 xff0c 对其飞行姿态角进行描述 xff0c 并在此基础上建立数学模型 四旋翼飞行器的原理 根据四旋翼飞行器的运动方式的特点将其飞行控制划分为四种基本的飞行控制方式 1
  • 数组名和函数名是什么东西

    数组名和函数名的本质都是一个 指向数组首地址或函数体的指针常量 的名字 规则1 xff1a 数组 61 指向数组首地址的指针常量 43 数组元素 简单说就是 xff0c 数组 61 指针常量 43 数组内容 xff0c 数组名就是这个指针常
  • RT-Thread进阶之低功耗PM组件应用笔记

    电源管理组件 嵌入式系统低功耗管理的目的在于满足用户对性能需求的前提下 xff0c 尽可能降低系统能耗以延长设备待机时间 高性能与有限的电池能量在嵌入式系统中矛盾最为突出 xff0c 硬件低功耗设计与软件低功耗管理的联合应用成为解决矛盾的有
  • 【STM32H750】玩转ART-Pi(一)——使用STM32CUBMX生成TouchGFX工程

    目录 STM32H750 玩转ART Pi xff08 一 xff09 使用STM32CUBMX生成TouchGFX工程 STM32H750 玩转ART Pi xff08 二 xff09 制作MDK的外部QSPI FLASH烧录算法 STM
  • 【STM32H750】玩转ART-Pi(二)——制作MDK的外部QSPI-FLASH烧录算法

    目录 STM32H750 玩转ART Pi xff08 一 xff09 使用STM32CUBMX生成TouchGFX工程 STM32H750 玩转ART Pi xff08 二 xff09 制作MDK的外部QSPI FLASH烧录算法 STM
  • linux驱动开发篇(四)—— platform平台设备驱动

    linux系列目录 xff1a linux基础篇 xff08 一 xff09 GCC和Makefile编译过程 linux基础篇 xff08 二 xff09 静态和动态链接 ARM裸机篇 xff08 一 xff09 i MX6ULL介绍 A
  • C语言变参函数和可变参数宏

    文章目录 一 变参函数的设计与实现1 变参函数初体验2 变参函数改进版3 变参函数 V3 0 版本3 变参函数 V4 0 版本4 变参函数 V5 0 版本 二 可变参数宏的设计与实现1 什么是可变参数宏2 宏连接符 的作用3 可变参数宏的另
  • 利用MDK的FLM文件生成通用flash驱动

    文章目录 前言一 FLM文件是什么 xff1f 二 FLM文件结构1 FlashPrg c2 FlashPrg c 三 解析FLM文件1 解析flm文件 四 设计flash驱动抽象层五 快速使用 前言 在进行Flash操作时 xff0c 一
  • 游标的概念和作用

    游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制 游标充当指针的作用 尽管游标能遍历结果中的所有行 xff0c 但他一次只指向一行 概括来讲 xff0c SQL的游标是一种临时的数据库对象 xff0c 即可以用来存放在数
  • 【STM32H750】从零编写MDK的FLM烧录算法

    文章目录 前言一 将代码中的图片资源下载到外部flash1 修改分散加载文件 二 MDK下载算法原理1 程序能够通过下载算法下载到芯片的原理2 算法程序中擦除操作执行流程3 制作FLM文件步骤 三 使用STM32CubeMX新建工程1 新建
  • 使用MDK开发树莓派pico RP2040之外部 flash下载算法

    文章目录 前言一 MDK下载算法原理1 程序能够通过下载算法下载到芯片的原理2 算法程序中操作执行流程3 创建MDK下载算法通用流程 二 树莓派pico下载算法制作步骤1 下载树莓派的MDK的程序模板2 修改输出算法文件的名字3 修改编程算
  • 单片机堆栈分配

    Code xff1a 表示程序所占用 FLASH 的大小 xff08 FLASH xff09 RO data xff1a 即 Read Only data xff0c 表示程序定义的常量 xff0c 如 const 类型 xff08 FLA