一、内存分布
1、地址详解
在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区
、堆区
、全局区(静态区)
、常量区
、代码区
,其中全局区中高地址分布着.bss
段,低地址分布着.data
段。
总分布如下:
内存高地址 | 栈区 |
---|---|
堆区 | |
.bss段 | |
.data段 | |
常量区 | |
内存低地址 | 代码区 |
1)栈区
-
临时创建的局部变量存放在栈区。
-
函数调用时,其入口参数存放在栈区。
-
函数返回时,其返回值存放在栈区。
-
const定义的局部变量存放在栈区。
2)堆区
-
堆区用于存放程序运行中被动态分布的内存段,可增可减。
-
可以有malloc等函数实现动态分布内存。
-
有malloc函数分布的内存,必须用free进行内存释放,否则会造成内存泄漏。
3)全局区(静态区)
全局区有.bss段和.data段组成,可读可写。
4).bss段
-
未初始化的全局变量存放在.bss段。
-
初始化为0的全局变量和初始化为0的静态变量存放在.bss段。
-
.bss段不占用可执行文件空间,其内容有操作系统初始化。
5).data段
-
已经初始化的全局变量存放在.data段。
-
静态变量存放在.data段。
-
.data段占用可执行文件空间,其内容有程序初始化。
-
const定义的全局变量存放在.rodata段。
6)常量区
-
字符串存放在常量区。
-
常量区的内容不可以被修改。
7)代码区
-
程序执行代码存放在代码区。
-
字符串常量也有可能存放在代码区。
2、数据存放位置
- RAM(随机存取存储器)
存储的内容可通过指令随机读写访问。RAM中的存储的数据在掉电是会丢失,因而只能在开机运行时存储数据。其中RAM又可以分为两种,一种是Dynamic
RAM(DRAM动态随机存储器),另一种是Static
RAM(SRAM,静态随机存储器)。栈、堆、全局区(.bss段、.data段)都是存放在RAM中。
- ROM(只读存储器)
只能从里面读出数据而不能任意写入数据。ROM与RAM相比,具有读写速度慢的缺点。但由于其具有掉电后数据可保持不变的优点,因此常用也存放一次性写入的程序和数据,比如主版的BIOS程序的芯片就是ROM存储器。代码区和常量区的内容是不允许被修改的,所以存放于ROM中。
二、编程验证
1)代码添加
首先,分别在Ubuntu
和keil
中创建文件添加代码如下:
#include <stdio.h>
#include <stdlib.h>
//定义全局变量
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\n");
}
int main( )
{
//定义局部变量
int a=2;
static int inits_local_c=2, uninits_local_c;
int init_local_d = 1;
output(a);
char *p;
char str[