编译过程中的链接地址对最终编译镜像文件的影响
MDK和交叉编译工具编译时都会指定程序的下载的地址(其实就是告诉程序它将在那个地址上开始执行),这有什么意义吗?
其实这么设计有原因的,因为这里涉及到全局变量和全局函数指针的地址问题,加入当你在编译时指定编译器这段程序会在0x0c000000地址上运行,因此全局变量和全局函数指针就会从0x0c000000上开始分配地址,此时如果你把这段程序烧录到0x0c000000地址上运行,变量的访问和指令存取不会有人任何问题,但是如果你将程序下载到0x00000000上运行时,在程序会在访问全局变量时,实际上这个变量地址分配的地址是0x00000001但是,因为你编译是连接地址不是0x00000000所以程序会到0x0c000001去读取这个变量,此时就会读到一个错误的值。对于函数指针也是相同的道理,但此时指令就跑飞了。
ARM处理器上的用处(相对跳转和绝对跳转)
绝对跳转:就是执行了这一条指令之后就会跳转到绝对跳转的指令中的地址去执行。
相对跳转:从当前地址偏移一定的偏移地址去执行一个程序。
将被编译到0xC0000000地址的代码放到0x00000000地址开始执行,如果它们只使用顺序执行或者相对跳转执行方式就可以正常运行(未使用全局变量和全局函数指针),但如果使用了绝对寻址,那么程序就跑飞了。
我们参照下面这段伪代码来说明这个情况。
指令编号 指令功能 指令1 :顺序执行 指令2 :顺序执行 指令3 :相对跳转到指令5 指令4 :顺序执行 指令5 :顺序执行 指令6 :绝对跳转到指令8 指令7 :顺序执行 指令8 :顺序执行
在编译、链接的时候,这段程序被告知放在0xC0000000地址空间,编译后烧录到0x00000000结果在存储设备中的存放结果为(每条指令以4字节计算):
指令地址 指令编号 指令功能 下条指令地址0x00000000 指令1: 顺序执行 当前地址+4 0x00000004 指令2: 顺序执行 当前地址+4 0x00000008 指令3: 相对跳转到指令5 当前地址+8 0x0000000C 指令4: 顺序执行 当前地址+4 0x00000010 指令5: 顺序执行 当前地址+4 0x00000014 指令6: 绝对跳转到指令8 0xC000001C 0x00000018 指令7: 顺序执行 当前地址+4 0x0000001C 指令8: 顺序执行 当前地址+4
程序从0x00000000开始运行直到第五条指令都是不会出错的,但是当执行完指令6后程序就会跑飞了,因为指令6是一条绝对跳转的指令但0xC000001C空间没有代码,这样程序就跑飞了。但当这段程序被放在0xC0000000起始空间时,开始执行指令1,然后采用相对寻址的方法就可以运行到指令6,在指令6执行时执行绝对寻址的方法从0xC0000014正确跳转到指令8所在的0xC000001C位置,这段代码运行正常。(参考博客:http://blog.sina.com.cn/s/blog_908da74601011bg6.html)
如图:
MDK编译后的STM32工程 map文件简单分析
只看map文件中有用的部分:
Code为程序代码部分
RO-data 表示 程序定义的常量const temp;
RW-data 表示 已初始化的全局变量
ZI-data 表示 未初始化的全局变量
Program Size: Code="18248" RO-data=320 RW-data=260 ZI-data=3952
Code, RO-data,RW-data ............flash
RW-data, ZIdata...................RAM (内存)
存储Size:
RO size: Code + RO_data
RW size: RW_data + ZI_data
ROM (minimum)size = Code + RO_data + RW_data (即烧/下载程序到FLASH/ROM时,所占用的最小空间)
Total ROM Size (Code + RO Data + RW Data)这样所写的程序占用的ROM的字节总数,也就是说程序所下载到ROM flash 中的大小。为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
RAM size: RW Data + ZI Data (即程序运行的时,RAM使用的空间)
一个ARM程序包含3部分:RO段,RW段和ZI段
RO是程序中的指令和常量
RW是程序中的已初始化变量
ZI是程序中的零初始化的变量
由以上3点说明可以理解为:
RO就是readonly,
RW就是read/write,
ZI就是zero
完事,今天好冷哎!
转载于:https://www.cnblogs.com/w-smile/p/10073790.html
编译过程中的链接地址对最终编译镜像文件的影响相关推荐
- 实验检测编译过程中的链接作用
/* 名称:实验检测编译过程中的链接作用 说明:以前一直不太了解编译过程中链接是到底干嘛的(其具体的作用是什么),只浅浅的了解到这个阶段就是将各个目标文件连接在一起,至于为什么要连接,怎么连接,不是很 ...
- vc2005编译过程中没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题? 的彻底解决
vc2005编译过程中"没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题"? 的彻底解决 收藏 快毕业了,为了工作的需要,需要使用庞大的VS2 ...
- 编译html成qch,在应用程序编译过程中运行qcollectiongenerator
我一直在研究一个名为RoboJournal的程序很长一段时间.下一版本包含完整的文档;每当用户按F1或单击RoboJournal程序中的帮助项目时,帮助文件将显示在Qt助手中(比简单地打开浏览器窗口以 ...
- C++编译过程中没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题? 的彻底解决...
今天本人用vs2005 sp1中文版,学习C++程序的过程中,在执行MFC程序时,在编译过程中出现如下问题: 相关问题:这里编译时可能出现以下问题 /************************* ...
- Apache Atlas 2.0.0编译过程中遇到的问题及解决方案
Atlas安装依赖: 1.Maven 3.5+,下载安装包解压后配置环境变量即可,详细步骤请自行百度,下载地址:http://maven.apache.org/download.cgi 2.Apach ...
- Qt编译过程中出现的问题
1.解压源码zip包的时候,要使用参数-a,否则编译会有问题. 2.编译过程中出现错误:QT /usr/include/X11/extensions/XIproto.h:1825: 错误:expect ...
- 编译过程中,termcap.h 文件找不到路径 licli.a终于生成
编译过程中,termcap.h 文件找不到路径 查看是linux 源码下找不到termcap.h文件 安装了所有关于*cap*的源码包也不起作用 今天终于解决了这个问题,搜termca ...
- 在以阶段划分的编译过程中,判断程序语句的形式是否正确属于()阶段的工作。
在以阶段划分的编译过程中,判断程序语句的形式是否正确属于()阶段的工作. A.词法分析 B.语法分析 C.语义分析 D.代码生成 答案:B 答案解析: 选项A这个阶段的任务是对源程序从前到后(从左到右 ...
- 锚链接html target,列锚标签()的target属性中,哪一个可以定义在新窗口中打开链接地址()。 - 问答库...
问题: [单选] 列锚标签()的target属性中,哪一个可以定义在新窗口中打开链接地址(). A . A_self B . B_blank C . C_parent D . D_to 在配置管理中, ...
最新文章
- 数据结构---基础概念
- 霍布森选择效应(Hobson choice Effect)
- matlab cell取一列,MATLAB cell struct
- Mule,目前综合状态最良好的开源ESB方案
- docker piwik
- nginx配置文件+本地测试请求转发到远程服务器+集群
- 功能Java示例 第5部分–将I / O移到外部
- Selenium Web 自动化 - 项目实战(三)
- paip.gui控件tabs控件加载内容的原理以及easyui最佳实现
- 微软Azure IoT
- python django开发工具_Django+python 开发神器
- “拯救网站运维经理赵明”已近尾声
- 著名TED演讲 《用肢体语言塑造你自己》 - Amy Cuddy
- 小米等部分手机机型不弹出对话框问题
- 基于拉丁超立方抽样与自适应策略的改进鲸鱼优化算法
- ConcurrentQueue TryPeek数据丢失
- 张裕公司创始人张弼士与李鸿章的交往
- rstp 转hls_EasyHLS实现将IPCamera摄像机的RTSP转HLS直播输出
- 编程趣事 100元x100元是否等于10000分x10000分
- 【书籍阅读】深入了解SNMP知识的书籍
热门文章
- java io流操作_十个Demo进行讲解Java中IO流的常用操作~
- Linux C实现简单的shell
- python安装虚拟环境出现错误_virtualenv 安装虚拟环境问题 请大神指点一二
- python爬虫爬图片教程_python爬虫实战之爬取京东商城实例教程
- Django模板中如何将函数的变量作为字典key并获取对应的value
- 计算机表示法是知识 表示法么,计算机三级考试关于IP地址知识点
- 十三、MySQL存储过程相关知识总结 + 案例讲解(强化)
- LeetCode 1844. 将所有数字用字符替换
- LeetCode 1039. 多边形三角剖分的最低得分(区间DP)
- 程序员面试金典 - 面试题 16.18. 模式匹配(逻辑题)