OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6343|回复: 5

stm32启动堆栈分配初始化

[复制链接]

6

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-8-18
在线时间
14 小时
发表于 2018-4-18 22:12:24 | 显示全部楼层 |阅读模式
1金钱
Q7VRUQ_Y`RXC]}]6SBMDY`9.png
在看过stm32f103的启动代码后发现,启动时为栈分配1KB的内存,堆分配512Byte内存。我个人认为1K的栈会不会太小了,于是在main函数拿了个数组试了一下,用STLink仿真。
1.arr数组长度为1024的时候发现sp指针指向了堆顶了,是不是说堆区和栈区是直接相连的呢?
2.arr数组长度为1024+512时,也就是初始化时堆和栈的总大小,此时sp指向了堆基,是不是说栈内存不够用的时候能占用堆区的内存呢?
3.arr数组长度为1024+512+328时(328为堆底减去0x20000000,也就是堆底相对SRAM起始地址之间还存在着328Byte的内存)此时SP指向了code末尾的地址,并且程序崩溃了。
如果平时使用数组的话,整形int类型数组长度为256就已经能把1K的栈用完,所以1k会不会优点小,求指点。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-4-19 01:43:13 | 显示全部楼层
只有静态变量区和栈区。  没用malloc(没设置heap),没有堆!
回复

使用道具 举报

6

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-8-18
在线时间
14 小时
 楼主| 发表于 2018-4-19 08:44:42 | 显示全部楼层
正点原子 发表于 2018-4-19 01:43
只有静态变量区和栈区。  没用malloc(没设置heap),没有堆!

那启动代码上面分配的512Byte是什么意思
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2018-4-19 09:36:09 | 显示全部楼层
本帖最后由 candylife9 于 2018-4-19 09:42 编辑

你的精神很值得我学习,虽然我也一直有这方面的疑惑,但是一直没有动手去试验,我都不知道启动代码里面分配的堆栈是怎么用法,特别是带操作系统的时候,操作系统里面也有分配堆空间。但是有些问题我还是可以回答。
1、堆和栈的空间是靠指针控制的,操作堆栈就是操作相应的指针。堆不足会内存分配失败,对栈没有影响。但是栈分配是动态的,经常性的,如果栈分配小了就会发生溢出,也就是栈指针指向非栈区。如果溢出的这部分恰好分配了静态或全局变量,会导致这些变量值被修改。或者这些变量的修改会覆盖栈的内容,导致程序崩溃。如果这部分没有分配静态全局变量,则这部分内存的存取是由栈指针控制了,按照先进后出的栈算法控制,对程序不会有影响(不考虑内存动态分配)。
2、1K的栈是足够的,本来嵌入式处理器的内存资源就有限,需要在写代码的时候时刻考虑到栈分配的问题,保证不会同时需要大量栈空间的情况。
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
发表于 2018-4-19 14:19:17 | 显示全部楼层
candylife9 发表于 2018-4-19 09:36
你的精神很值得我学习,虽然我也一直有这方面的疑惑,但是一直没有动手去试验,我都不知道启动代码里面分配 ...

一般1k是够了的,如果不放心可以加。前提是你ram够大
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2018-10-26
在线时间
0 小时
发表于 2018-10-26 16:59:08 | 显示全部楼层
本帖最后由 山道苍狼 于 2018-10-26 17:00 编辑

这个最近刚好看了,首先你的实验是正确的,按照理论来说的确会发生这样的情况。如果不使用MicroLIB的话,在单片机启动的时候首先会进入SystemInit将时钟初始化,之后进入__main(注意不是main,__main执行到最后才会进入main),它会将ZW段复制到0x8000000的地址位置,也就是Flash开始的位置,之后是C库函数初始化使用到的堆栈。排在后面的是你在启动文件中申请的堆和栈,堆在低地址,然后是栈排在高地址,向下增长。即便你不使用C标准库中的malloc,也会将堆空间申请出来,所以不使用的时候最好将栈设置为0。具体可以去看https://blog.csdn.net/qlexcel/article/details/78884379,这篇写的非常好
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 09:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表