参考代码:Embedded/stm32/var_Placement · guorong/study - 码云 - 开源中国 (gitee.com)
写一个如下所示的代码,可以查看各种类型的变量的存储位置
#include"stdlib.h"
int g_var;
int g_var_init_z=0;
int g_var_init =10;
const int c_g_var;
const int c_g_var_z=0;
const int c_g_var_init=20;
int main()
{
static int s_var;
static int s_var_init_z=0;
static int s_var_init =30;
int var;
int var_init_z=0;
int var_init =40;
int *ptr = (int *)malloc(sizeof(int));
int tmp= g_var+ g_var_init_z +g_var_init + c_g_var + c_g_var_z + c_g_var_init + s_var + s_var_init_z + s_var_init + var + var_init_z + var_init;
int *p[14];
int i=0;
p[i++] = (int *)&g_var;
p[i++] = (int *)&g_var_init_z; ;
p[i++] = (int *)&g_var_init ;
p[i++] = (int *)&c_g_var ;
p[i++] = (int *)&c_g_var_z ;
p[i++] = (int *)&c_g_var_init ;
p[i++] = (int *)&s_var ;
p[i++] = (int *)&s_var_init_z ;
p[i++] = (int *)&s_var_init ;
p[i++] = (int *)&var ;
p[i++] = (int *)&var_init_z ;
p[i++] = (int *)&var_init;
p[i++] = (int *)ptr;
p[i++] = (int *)p;
while(1)
{
}
}
还需要看一下map文件,先确认一下各个区域的范围
可以看出主要分为以下4个区域
- flash区域为0x08000000开始
- .bss段为0x20000000的0x74个字节
- 堆区为:0x20000078开始的0x200个字节
- 栈区为:0x20000278开始的0x400个字节
运行结果如下
可以看出结论为:
- 可读写的未初始化全局变量放置在bss段,并被初始化为0
- 可读写初始化为0的全局变量放置在bss段,并被初始化为0
- 可读写的初始化为10的全局变量,放置在bss段,并初始化为10
- 只读全局未初始化变量放在flash中,并初始化为0
- 只读初始化为0的全局变量放置在flash中,并被初始化为0
- 只读初始化为20的全局变量放置在flash中,并初始化为20
- 可读写的未初始化静态变量放置在bss段,并被初始化为0
- 可读写初始化为0的静态变量放置在bss段,并被初始化为0
- 可读写的初始化为30的静态变量,放置在bss段,并初始化为30
- 可读写的未初始化局部变量放置在栈中,值为不确定的值
- 可读写初始化为0的局部变量放置在栈中,并被初始化为0
- 可读写的初始化为40的局部变量,放置在栈中,并初始化为40
- malloc申请的变量,放置在堆中,值为不确定
- 最后一个是数组自己的地址,相当于一个局部变量,存在了栈
总结为表格如下
读写属性 | 定义方式 | 是否初始化 | 最终变量放置位置 | 初始化值 |
---|---|---|---|---|
可读写 | 全局 | 否 | bss段 | 0 |
可读写 | 全局 | 0 | bss段 | 0 |
可读写 | 全局 | 10 | bss段 | 0 |
只读 | 全局 | 否 | flash | 0 |
只读 | 全局 | 0 | flash | 0 |
只读 | 全局 | 20 | flash | 0 |
可读写 | 静态 | 否 | bss段 | 0 |
可读写 | 静态 | 0 | bss段 | 0 |
可读写 | 静态 | 30 | bss段 | 0 |
可读写 | 局部 | 否 | 栈 | 不确定 |
可读写 | 局部 | 0 | 栈 | 0 |
可读写 | 局部 | 40 | 栈 | 40 |
可读写 | malloc | 否 | 堆 | 不确定 |
可读写 | 局部 | 否 | 栈 | 不确定 |