机械荟萃山庄

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 1431|回复: 6

关于链接器的一点小小经验

[复制链接]
发表于 2021-8-5 12:11:33 | 显示全部楼层 |阅读模式
本帖最后由 皮卡丘不会打乒乓球 于 2021-8-5 12:15 编辑

链接器
昨天遇到了一点问题,关于嵌入的地址分配的问题。
一个项目片内设计有两个不同的主程序,放在不一样的位置上。一个用于从外下载数据更新应用程序,一个用在正常的应用程序状态下,两个程序之间可以通过重置PC指针到对方入口的办法调用。  由于更换了MCU型号,内存部分内容被修改,导致这个跳转的部分失效,其余的功能都是正常的。
我把BUG反馈给了负责那个部分的工程师,他那边看了一下编译报告MAP文件,确认了跳转的标志位分配在两个新旧程序之间时不一致的,然后发了新的代码给我,测试确认了没有问题。

我查看了版本变化,具体的修改就是把原先变量绑定的段重新定义了几个子段,然后把原先变量一个个的绑定到对应的子段里面去。

趁这个机会聊几句链接器的事吧,我了解不是特别深入,有写地方可能不对,希望指正。

链接器本质的作用就是把编译产生的段文件(汇编代码片段),按照存储模型进行分配。对于这个过程需要一个指导文件,(ARM工程下为ld文件,TI工程下叫做CMD文件)。这个指导文件内容主要包括两个部分,存储模型(寻址空间)的描述和段的分配。
存储模型会分为很多个块,复杂一些的甚至会有页的概念。每一个块都会定义起始地址与长度,块可以预先填充。
段是编译产生的汇编产生的数据块与代码块,通过对应的标识,链接器就可以把这些东西分配到存储空间内。编译一共可以产生5种基本的段    其中.text,.data,.sect属于被初始化的段,而.bss与.unsect属于未初始化的部分及被初始化为0的全局变量与静态变量,
  以上5种都属于静态分配,均会占据空间。局部变量会被放在堆栈(stack,heap)中。段可以创建子段,用于更加细致的分配(我的程序被修改的就是这一部分的定义)。

段内容使用有两种概念 加载与运行。
加载就是从原始存储地址读取,运行就是每次使用的时候读的位置。
有些程序比如本身存储于NVM中,但是实际上实在RAM中运行的。在使用前必须将对应的段搬运到对应RAM位置。未初始化的段由于在最开始没有实际的有意义的数据,所以需要且仅需要指定一个运行地址即可。

这个链接器部分是伪指令,有专门的关键字及语法。具体内容很复杂,暂时不去展开学习了。毕竟我不是专门弄编译器的,后面有机会再研究把。
做从未做过的事情,做一个酷炫的仔
回复

使用道具 举报

47

主题

8848

帖子

4万

积分

论坛元老

Rank: 8Rank: 8

积分
42113
发表于 2021-8-5 12:21:20 | 显示全部楼层
小土表示依旧看不懂....
但还是能借用俺恩人的总结性发言:牛逼

点评

牛逼是别人的,我就是发现了个bug,顺带学习了一下而已  发表于 2021-8-5 12:22
回复 支持 反对

使用道具 举报

发表于 2021-8-5 12:47:29 | 显示全部楼层
迷茫表示依旧看不懂....
但还是能借用土老板的总结性发言:屌

点评

恩人,你今儿咋没喊求带…  发表于 2021-8-5 13:33
许多东西,你放下了,是个永远的困扰,每天都出现,无法避免。
回复 支持 反对

使用道具 举报

1万

主题

4万

帖子

26万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
267578
发表于 2021-8-5 12:50:35 | 显示全部楼层
挺好,要常弄这些,对思路有加强作用
回复 支持 反对

使用道具 举报

19

主题

2831

帖子

1万

积分

论坛元老

Rank: 8Rank: 8

积分
14897
发表于 2021-8-5 13:11:23 | 显示全部楼层
伪指令超级有用,而在C里,也有一些库是专门定义移植特征的,不包含这些头文件就没办法执行。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|机械荟萃山庄 ( 辽ICP备16011317号-1 )

GMT+8, 2024-12-30 02:21 , Processed in 0.103798 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表