聊聊内存那些事(基于STM32单片机系统)

单片机的RAM和ROM

单片机的ROM,叫只读程序存储器,是FLASH存储器构成的,如U盘就是FLASH存储器。所以,FLASH和ROM是同义的。单片机的程序,就是写到FLASH中了。

而RAM是随机读/写存储器,用作数据存储器,是在运行程序时,存放数据的。

内存区

内存主要分为:代码区、常量区、静态区(全局区)、堆区、栈区这几个区域。

l  代码区:存放程序的代码,即CPU执行的机器指令,并且是只读的。

l  常量区:存放常量(程序在运行的期间不能够被改变的量,例如: 25,字符串常量”dongxiaodong”, 数组的名字等)

l  静态区(全局区)静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放

l  堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏

l  栈区:存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存(分配内存 , 回收内存),不需要开发人员来手动管理。栈区就像是一家客栈,里面有很多房间,客人来了之后自动分配房间,房间里的客人可以变动,是一种动态的数据变动。

STM32F103C8T6中

OM起始地址为:0x8000000, 大小为:0x10000 (64K)

只读的,存放着代码区和常量区

RAM起始地址为:0x20000000,大小为:0x5000  (20K)

可读可写的,存放着静态区、栈区和堆区

STM32各区详细介绍:

代码区:

l  代码区存放着程序编译后的CPU指令

l  函数名称是一个指针,可以通过查询函数名称所处的内存地址,查询函数存放的区域

//函数声明
void dong();
//主函数定义
int main(void)
{
  //串口初始化
    Uart1_Init(115200);
    //函数调用
  dong();
    //输出test函数地址
    printf("dong() addrs : 0x%p\n",dong);

    while(1);
}
void dong(){
     //输出main函数地址
     printf("mian() addrs : 0x%p\n",main);
}

输出:

可见0x08000c2d和0x08000be9都在ROM里的代码区

常量区

指针可以指向常量也可以指向变量的区域,通过指针(char *p)来测试一下常量与变量去的地址变化。

void dongxiaodong_fun(){
   char *p=NULL;//定义一个指针变量
     //常量
     p="2020dongxiaodong";//指针指向一个常量
   printf("addr1:0x%p\r\n",p);//输出常量地址
     //变量
     char data[]={"dong1234"};
     p=data;//指针指向一个变量
   printf("addr2:0x%p\r\n",p);//输出变量地址
}

输出:

可见常量的地址在ROM里的常量区,局部变量在RAM的栈空间下

静态区

静态区包括静态变量和全局变量,静态变量通过static修饰,一旦初始化则一直占用RAM空间

int global_a;//全局变量,默认值为0
static int global_b;//静态全局变量,默认值为0
void fun(){
  static int c;//静态变量,默认值为0
    printf("static int c add
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值