专栏中心

EEPW首页 > 专栏 > 通过map文件了解堆栈分配(STM32、MDK5)--避免堆栈溢出

通过map文件了解堆栈分配(STM32、MDK5)--避免堆栈溢出

发布人:电子禅石 时间:2020-04-23 来源:工程师 发布文章

环境:STM32F103C8T6,MDK5

在最近的一个项目的开发中,每当调用到一个函数,程序就直接跑飞。debug跟进去看不出什么逻辑错误,但发现函数内局部变量声明之后,全局变量的值被清零,后来查看局部变量地址已经超出栈的范围,于是确定是栈溢出。如果不稍微了解一下堆栈,在开发过程中可能碰到各种奇怪的错误。

.map和startup.s文件

MAP 文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。

在MDK5中,在项目中双击Target就能自动打开.map文件。

技术图片

Startup.s文件是系统的启动文件,主要包括堆和栈的初始化配置、中断向量表的配置以及将程序引导到main( )函数等。

Startup.s主要完成三个工作:栈和堆的初始化、定位中断向量表、调用Reset Handler。

 堆栈作用

栈(stack)空间,用亍局部变量,函数调时现场保护和返回地址,函数的形参等。

堆(heap)空间,主要用亍劢态内存分配,也就是说用 malloc,calloc, realloc 等函数分配的变量空间是在堆上。

堆栈在内存分布

在map文件中搜索STACK或者HEAP,在接近文件底部的位置可以看到SRAM的分配,如下图。

技术图片

 

 从上图中可以看出SRAM空间用来存放:1、各个文件中声明和定义的全局变量、静态数据和常量;2、HEAP区;3、STACK区。

STM32的堆栈是存放在SRAM中的,分配堆栈大小需要考虑SRAM容量。

在.map文件中的Image Symbol Table底下可以找到如下图所示堆栈分布信息。

技术图片

堆在使用时会从低地址往上加,而栈是从__initial_sp开始往下减。以上图中的堆栈地址为例,malloc会从0x20002248开始往上加,局部变量的分配会从0x20004448开始往下减。如果入栈元素过大,使得入栈元素的地址访问到了0x20002448之后的内容,就发生了栈溢出,首先会改变堆中的元素值,如果入栈元素够大,可能会直接改变HEAP后面的全局变量。同理,当动态申请的内存过大时,堆中变量越界到栈中,此时就发送堆溢出。

避免产生这类错误的产生,程序设计时就应该考虑变量大小和堆栈大小是否合适。一个是减少过大的临时变量和动态申请内存,另一个是在SRAM空间允许的情况下增大堆栈大小,如上图中栈大小是8192字节,堆大小是512。

 堆栈大小设置

MDK5中可以通过修改startup.s文件来设置堆栈大小,只需要修改startup.s文件中的Stack_Size和Heap_Size即可,如下图所示。

 技术图片

KEIL Uvison5中默认生成的startup.s文件是只读的,无法修改,只需要设置一下该文件的属性,把只读取消即可。

 


专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词:

相关推荐

可能用于边缘计算的新2D芯片

用于消费电子产品的ispMACH 4000ZE CPLD系列

视频 2010-01-13

​Henry Samueli:让你手机里的调制解调器成为现实

机卡分离

资源下载 2007-02-13

英特尔官宣裁员重组计划,CEO陈立武引领变革

EDA/PCB 2025-04-25

Altium Designer概述 上

视频 2010-01-13

TI DC/DC 转换器TPS54620 简单易用的负载点设计

视频 2010-01-13

地平线与博世深化合作,辅助驾驶产品获多家车企项目定点

BQ3060:符合 SBS 1.1 的电量监测计和保护器

视频 2010-01-13

无钥匙≠无感知:UWB技术如何重新定义人车交互边界

Altium Designer概述 下

视频 2010-01-13

未来的芯片将比以往任何时候都更热

EDA/PCB 2025-04-25

Molex莫仕加深本土化创新,支持中国汽车行业蓬勃发展

汽车电子 2025-04-25

英特尔用AI技巧发现数据中心芯片中隐藏的缺陷

在LLM方面Google取得成功,而Meta和OpenAI则跌跌撞撞

智能计算 2025-04-25

DC_DC Solution

资源下载 2007-02-13

德州仪器PLL1707-Q1如何定义下一代音视频系统

更多 培训课堂
更多 焦点
更多 视频

技术专区