STM32内存与堆栈

内存基本构成

  可编程内存在基本上分为这样的几大部分:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。

  静态存储区:内存在程序编译的时候就已经分配好了,这块内存在程序的整个运行期间都存在。它主要存放静态变量、全局变量和常量

  栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率高,但是分配的内存容量有限。栈空间用于局部变量、函数调用、函数的参数等。

  堆区:亦称动态内存分配。程序在运行的时候用mallocnew申请任意大小的内存,程序员自己负责在适当的时候用freedelete释放内存,动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放动态内存。但是,良好的编程习惯是:如果某动态内存不在使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。(从内存区域的起始地址开始分配给各个全局变量和静态变量:0x200000004

 

按照这个说法,在startup_stm32f10x_hd文件里面设置了:

Heap_Size     EQU  0x00000000

 

也就是没有任何动态内除分配。

这样,内存=静态存储区+栈区

不存在堆!!!!!

因为没有用malloc来动态分配内存,所以提到的一切堆区,其实就是静态内存区。

 

另外,经过测试,确实是这样。

STM32的内存分配,应该分为两种情况:

1、使用了系统的malloc

2、未使用系统的malloc

 

第一种情况(使用malloc

STM32的内存分配规律:从0x20000000开始依次为:静态存储区+堆区+栈区;

 

第二种情况(不使用malloc

STM32的内存分配规律:从0x20000000开始依次为:静态存储区+栈区;

 

第二种情况不存在堆区

所以,一般对于开发板历程,实际上,没有所谓的堆区的概念,而仅仅是:静态存储区+栈区。无论哪种情况,所有的全局变量,包括静态变量之类的,全部存储在静态存储区。紧跟静态存储区之后的,是堆区(如没使用到malloc,则没有该区),之后是栈区。

此博文借鉴了原子哥的,发表此篇以此记录

 

补充知识:C语言

(1)栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈。(切记不要在函数里面放N多局部变量,尤其是大数组

(2)堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收,分配的方式类似于数据结构中的链表。

(3)全局区(静态区)(static):全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域;未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统自动释放。

(4)文字常量区:常量字符串就是存放在这里的;

(5)程序代码区(ROM):存放函数体的二进制代码。

(6)堆是向上增长,栈是向下增长。

 

//STM32查找栈增长方向,结果保存在stack_dir里面
//0,向下增长;1,向上增长.
staticu8 stack_dir;

//查找栈增长方向,结果保存在stack_dir里面.
voidfind_stack_direction(void)
{
   static u8 *addr=NULL; //用于存放第一个dummy的地址。
   u8dummy;              //用于获取栈地址 
   if(addr==NULL)    //第一次进入
   {                          
       addr=&dummy;     //保存dummy的地址
       find_stack_direction ();  //递归 
   }else               //第二次进入 
 {  
       if(&dummy>addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的
       else stack_dir=0;          //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的.  
 }

一般CPU的栈增长方向都是向下的

 

大端模式:低位字节存在高地址上,高位字节存在低地址上 
小端模式:高位字节存在高地址上,低位字节存在低地址上

//CPU到底是大端还是小端,可以通过如下代码测试:
//CPU
大小端
//0,
小端模式;1,大端模式.
static u8 cpu_endian;

//
获取CPU大小端模式,结果保存在cpu_endian里面
void find_cpu_endian(void)

 int x=1;
 if(*(char*)&x==1)cpu_endian=0; //
小端模式 
 else cpu_endian=1;    //
大端模式  
}
//
以上测试,STM32,你会得到cpu_endian=0,也就是小端模式.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值