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

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”);)存放在堆上。

相关文章:

  • 【Zephyr 系列 11】使用 NVS 实现 BLE 参数持久化:掉电不丢配置,开机自动加载
  • 从零开始基于Ubuntu18搭建Gazebo地图仿真环境
  • Ubuntu 系统.sh脚本一键部署内网Java服务(组件使用docker镜像,宕机自启动)
  • D3.js与vue3力导向图开发全流程
  • N8N概述
  • 【Linux】(1)—进程概念-⑤进程调度
  • 和芯 SL6341 (内置FLASH) 国产USB 3.0HUB芯片 替代 GL3510 VL817
  • Linux 中替换文件中的某个字符串
  • Kafka 快速上手:安装部署与 HelloWorld 实践(二)
  • Unity 中的颜色空间
  • 【公益护航青春路】 “成长的秘密花园”青春期身心成长讲座走进校园
  • JDBC(二) 综合案列、SQL注入问题、封装工具类、ORM
  • robot_lab——rsl_rl的train.py整体逻辑
  • 【UEFI系列】SEC阶段讲解
  • 嵌入式开发之STM32学习笔记day22
  • solidity中sar和>>的区别
  • gvim比较两个文件不同并合并差异
  • 【人工智能】一些基本概念
  • C++_哈希表
  • 智能运维如何让变电所“无人值守”还能降本增效?
  • 鄂州手机网站设计/网站推广怎么弄
  • 公司网站建设考核/环球网今日疫情消息
  • 免费做司考真题的网站/抖音广告
  • vps如何做网站步骤/国内网络营销公司排名
  • 九年级上册信息技术做网站/西安百度seo推广电话
  • 服务好的高端网站建设公司/seo推广方法集合