1.4.2链接脚本,位置无关码

在这里插入图片描述
secname就是section name,表示段名。

start为起始地址,即运行时的地址(runtime addr),也是重定位地址(relocate addr),程序运行时,会去该跳到该地址去执行。

AT(ldadr)为加载地址(Load Address),不写时,Load Address = runtime address,如果load address不等于runtime address,程序本身要重定位

contents 表示内容,可以指定文件(比如start.o),也可以指定段(如代码段(.text))*。

**通过设置重定位地址和加载地址,就可以实现将指定段的数据重定位。**如下图,表示在bin文件中,data段处于0x800的位置,但是程序运行时,data段处于0x3000,0000的位置。所以,我们软件上要将0x800的data段重定位到0x3000,0000位置。
在这里插入图片描述

在这里插入图片描述
如上图所示,其中.表示当前位置。将text代码段放在0x3000,0000,*(.text)表示所有的代码段,ALIGN(4)表示4字节对齐。所以,就是将所有的代码段四字节对齐的形式放在0x3000,0000起始的位置。

然后,是所有的只读数据段,数据段,bss和common,他们都是以四字节对齐的形式排列。

其中,bin文件,elf文件中都不存在bss段,我们软件上要将这个段清零。

重定位之前的代码,与地址无关,叫做位置无关码

怎么写位置无关码的程序(使用位置无关码,不使用绝对地址,最根本的办法是看反汇编):

  1. 使用相对跳转命令B/BL;
  2. 重定位前,不可以使用绝对地址,比如,不可以访问全局/静态变量;不可以访问有初始值的数组(rodata,data)
  3. 重定位之后,使用绝对跳转命令跳到runtime address,比如,ldr pc, =main

在这里插入图片描述
在这里插入图片描述
将代码段的runtim address设为0x3000,0000和0x3000,0000,查看反汇编码如上。

**这时候sdram还没有初始化完成,我们跳到sdram上,是不是程序执行会出问题?**其实,这里使用的是相对跳转指令,并不是真的跳到0x3000,xxxx的地方去执行,而是跳转到相对位置去执行,这里的相对位置为PC+offset,是由链接器计算出来。比如,假设程序从0x3000,0000执行,当前指令地址0x3000,005c,那么就会跳到0x3000,0478;如果从0运行,当前指令地址为0x5c,会跳到0x478;如果从0x3200,0000运行,当前指令地址为0x3000,005c,会跳到0x3200,0478;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值