嵌入式-ARM-学习总结(4):重定位

一、重定位

一般学习一个知识点,需要知道是什么,在什么情况下用,怎么用。这三步走,即可把一个知识点吃透。

那重定位是什么呢?

1.重定位是什么

重定位实际上就是在运行一段位置无关码PIC,让这段PIC(也就是重定位代码)从运行地址处把整个程序镜像拷贝一份到链接地址处,完了之后使用一句长跳转指令从运行地址处,直接跳转到链接地址去执行同一个函数,这样就实现了重定位之后的无缝连接。

这个里面出现一个名词位置无关码,这是什么呢?

2.位置无关编码与位置有关编码

位置无关编码(PIC,postition independent code):回避源文件被编码成二进制可执行程序时编码方式与位置(内存地址)无关。

**位置有关编码:**汇编源码编码成二进制可执行程序后和内存地址是有关的。
对比:位置无关代码要好一些,适应性强,放在哪里都能正常运行;位置有关代码就必须运行在链接时指定的地址上,适应性差。位置无关码有一些限制,不能完成所有功能,有时候不得不使用位置有关代码。

3.为什么需要重定位呢

因为对于有些时候,链接地址和运行地址必须是不同地址。而且还不能全部使用位置无关代码,所以需要使用重定位来实现分散加载。(这里的分散加载相当于一种手工的重定位)

4.链接地址和运行地址

链接地址:链接时指定的地址(指定方式:Makefile中用-Ttext,或者链接脚本)
运行地址:程序实际运行时的地址(指定方式:由实际运行时被加载到内存的哪个位置说了算)

5.重定位的使用

练习:在SRAM中将代码从0xd0020010重定位到0xd0024000。
思路:
第一步:通过链接脚本将代码链接到0xd0024000
第二步:dnw下载时将bin文件下载到0xd0020010
第三步:代码执行时通过代码前段的少量位置无关码将整个代码搬移到0xd0024000
第四步:使用一个长跳转到0xd0024000处的代码继续执行,重定位完成

第一步加上第二步,就保证了:代码实际下载运行在0xd0020010,但是却被链接在0xd0024000。从而为重定位奠定了基础。
当我们把代码链接地址设置为0xd0024000时,实际隐含意思就是我这个代码将来必须放在0xd0024000位置才能正确执行。如果实际运行地址不是这个地址就要出事(除非代码是PIC位置无关码),当以上都明白了后,就知道重定位代码的作用就是:在PIC执行完之前(在代码中第一句位置有关码执行之前)必须将整个代码搬移到0xd0024000位置去执行,这就是重定位。

长跳转和短跳转的区别
当链接地址和运行地址相同时,短跳转和长跳转实际效果是一样的;但是当链接地址不等于运行地址时,短跳转和长跳转就有差异了。这时候短跳转实际执行的是运行地址处的那一份,而长跳转执行的是链接地址处那一份。

6.例子:
//start.s文件
#define WTCON		0xE2700000

#define SVC_STACK	0xd0037d80

.global _start					// 把_start链接属性改为外部,这样其他文件就可以看见_start了
_start:
	// 第1步:关看门狗(向WTCON的bit5写入0即可)
	ldr r0, =WTCON
	ldr r
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值