当前位置: 首页 > ds >正文

keil编译工程,结合map文件和bin文件,实测C语言中不同类型的变量存储在不同的内存区域

使用keil编译工程,分析不同的变量存放的数据段;
代码工程如下

#include <stdio.h>
#include <stdlib.h>static char dujunqiu_static_data[64] = {1,2,3};			// 已初始化非0 的静态变量,存放 .data段
static char dujunqiu_static_data_zero[32] = {0};		// 已初始化为0 的静态变量,存放 .bss段
static char dujunqiu_static_data_uninit[32];			// 未初始化 的静态变量,   存放 .bss段
char dujunqiu_data[32] = {1,2,3};						// 已初始化非0 的全局变量,存放 .data段
char dujunqiu_bss[64];									// 未初始化 的静态变量,   存放 .bss段int main(void)
{char *dujunqiu_const1="hello-1 world";  			// 字符串常量区, 存放只读区char dujunqiu_const2[222]="hello-2 world";          // 字符串常量区, 存放只读区char dujunqiu_const3[333]={0};						// 临时数据变量,存放栈上printf("str=%s--%s %d\n", dujunqiu_const1, dujunqiu_const2,dujunqiu_const3[0]);printf("str=%d %d \n", dujunqiu_data[0], dujunqiu_bss[0]);return 0;}

网上搜索一下定义

段名说明
.constdata只读常量数据段,属于RO-data。
.text代码段。用来存放程序执行代码的内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读。也有可能包含一些只读的常数变量,例如字符串常量等。
.data数据段。data 段用于存储已经赋初值(非零)的全局变量,且变量占有实际的内存空间。本段的内容由程序初始化,因此会占用exe文件空间。
.bss数据段,Block Started by Symbol。bss段用于存储未赋初值的全局变量和静态局部变量,这些变量在程序运行前会被初始化为0或NULL。另外,初始化为零的全局变量和静态局部变量也会存储在bss中的数据不分配实际的空间,只体现为一个占位符,只记录数据所需空间的大小,因此不会占用exe文件空间。bss段的大小从可执行文件中得到 ,然后链接器得到这个大小的内存块,紧跟在data段后面。
heap堆。用于存放运行中被动态分配的内存段,可动态扩张或缩减。例如,malloc分配的内存就在堆上。
stack栈。用于存放程序临时创建的局部变量,即:函数括弧“{}”中定义的临时变量。注意,不包括用static声明的变量,static声明的变量存储在data段中。当函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。

全局变量
map文件截图示例,全局变量的存放位置应该是比较清晰的,搜素一下关键字就可以直接查询到;
map文件里面分为本地符号"Local Symbols" 和 全局符号"Global Symbols",所以行号不是连续的;
在这里插入图片描述

字符串常量
根据编辑的.bin文件,可以识别到hello-1和hello-2字段;
在这里插入图片描述

对比map文件的起始地址记录,两个都是只读区RO;不过一个是code类型,一个是date类型;(前面有几个其它数据,起始地址没有完全对齐)
并且0xde=222,刚好和代码里面的数组长度对上了
在这里插入图片描述
进一步搜索关键字 222
map文件刚好可以搜索到一个222长度的数据,在 constdata段
在这里插入图片描述
找不到333长度的字段,说明 "dujunqiu_const3"在 stack上,运行时候才会分配;
在这里插入图片描述

注意:
1:以上是基于keil编译代码进行map文件分析,不同的编译器可能存在不同的编译策略,最好以实测为准;
2:C语言将字符串字面量存放在常量区是为了保证其不可变性、提高内存效率,并兼容历史设计。实际编程中,如果需要修改字符串,应使用字符数组或堆内存。
3:字符数组(如char s[] = “abc”;)会将字符串拷贝到栈或全局区,是可修改的。(比如 dujunqiu_const2)
动态分配的字符串(如char *s = malloc(4); strcpy(s, “abc”);)存放在堆上。

http://www.xdnf.cn/news/12628.html

相关文章:

  • 柴油发电机组接地电阻柜的作用
  • yolov8自训练模型作为预训练权重【增加新类别】注意事项
  • 我用Amazon Q写了一个Docker客户端,并上架了懒猫微服商店
  • Web 3D协作平台开发案例:构建制造业远程设计与可视化协作
  • PC端直接打印功能(包括两张图片合并功能)
  • html 滚动条滚动过快会留下边框线
  • 2022年CSP-S1提高级第一轮题解
  • C++11新增标准讲解(上)
  • 【递归、搜索与回溯】专题三 穷举vs暴搜vs回溯vs剪枝
  • 【Vue】指令补充+样式绑定+计算属性+侦听器
  • 6.6 打卡
  • 西门子 S7-1200 PLC 海外远程运维技术方案
  • vue3+TS+eslint9配置
  • 《强连通分量》题集
  • 如何在Windows本机安装Python并确保与Python.NET兼容
  • day46python打卡
  • 1.4 编译库:静态库、动态库
  • Java并发包中的管程:Lock和Condition
  • 基于STM32语音识别柔光台灯
  • 基于深度学习的无人机轨迹预测
  • 《ERP原理与应用教程》第3版习题和答案
  • VSCode - VSCode 放大与缩小代码
  • 嵌入式开发之STM32学习笔记day22
  • 深入解析:为什么 Redis 比 MySQL 快
  • 如何轻松、安全地管理密码(新手指南)
  • 创客匠人:如何通过精准定位实现创始人IP打造与知识变现
  • [C语言实战]C语言操作MySQL数据库(八)
  • Ubuntu18.6 学习QT问题记录以及虚拟机安装Ubuntu后的设置
  • 下载和安装Visual Studio(开发ASP.NET MVC应用)
  • 华为仓颉语言初识:并发编程之同步机制(上)