在看过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会不会优点小,求指点。
那启动代码上面分配的512Byte是什么意思
你的精神很值得我学习,虽然我也一直有这方面的疑惑,但是一直没有动手去试验,我都不知道启动代码里面分配的堆栈是怎么用法,特别是带操作系统的时候,操作系统里面也有分配堆空间。但是有些问题我还是可以回答。
1、堆和栈的空间是靠指针控制的,操作堆栈就是操作相应的指针。堆不足会内存分配失败,对栈没有影响。但是栈分配是动态的,经常性的,如果栈分配小了就会发生溢出,也就是栈指针指向非栈区。如果溢出的这部分恰好分配了静态或全局变量,会导致这些变量值被修改。或者这些变量的修改会覆盖栈的内容,导致程序崩溃。如果这部分没有分配静态全局变量,则这部分内存的存取是由栈指针控制了,按照先进后出的栈算法控制,对程序不会有影响(不考虑内存动态分配)。
2、1K的栈是足够的,本来嵌入式处理器的内存资源就有限,需要在写代码的时候时刻考虑到栈分配的问题,保证不会同时需要大量栈空间的情况。
这个最近刚好看了,首先你的实验是正确的,按照理论来说的确会发生这样的情况。如果不使用MicroLIB的话,在单片机启动的时候首先会进入SystemInit将时钟初始化,之后进入__main(注意不是main,__main执行到最后才会进入main),它会将ZW段复制到0x8000000的地址位置,也就是Flash开始的位置,之后是C库函数初始化使用到的堆栈。排在后面的是你在启动文件中申请的堆和栈,堆在低地址,然后是栈排在高地址,向下增长。即便你不使用C标准库中的malloc,也会将堆空间申请出来,所以不使用的时候最好将栈设置为0。具体可以去看https://blog.csdn.net/qlexcel/article/details/78884379,这篇写的非常好
一周热门 更多>