堆(HEAP)
用来储存全局变量,静态变量以及内存管理分配的内存空间。堆的生长方向,都是向上的。
栈(STACK)
用来储存局部变量。不同的CPU,增长方向不同,arm的CPU一般为向下增长。
栈的增长方向测试代码:
//保存栈增长方向
//0,向下增长;1,向上增长.
static u8 stack_dir;
//查找栈增长方向,结果保存在stack_dir里面.
void find_stack_direction(void)
{
static u8 *addr=NULL; //用于存放第一个dummy的地址。
u8 dummy; //用于获取栈地址
if(addr==NULL) //第一次进入
{
addr=&dummy; //保存dummy的地址
find_stack_direction (); //递归
}
else //第二次进入
{
if(&dummy>addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的.
else stack_dir=0; //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的.
}
}
在程序里面,所有的内存分为:堆+栈,他们各自的起始地址和增长方向不同,而且没有一个固定的界限,所以一旦堆栈冲突,系统就会崩溃,通常会进入到HardFault_Handler。有时还会出现全局变量被局部变量篡改的现象,这是因为栈溢出到堆的区域,将储存全局变量的地址直接拿过来用。
避免堆栈溢出的方式有两种:不要在函数里面定义太多太大的局部变量,尤其是大的数组,还可以直接改变堆栈的大小。堆栈的大小,我们可以在STM32的启动文件startup_stm32f10x_hd.s中设置(文件开头处)。
Stack_Size EQU 0x00000400
Heap_Size EQU 0x00000200
本博客整理自网络,仅供学习参考,如有侵权,联系删除。邮箱:[email protected]