代码重定位实战1~2

《朱老师物联网大讲堂》学习笔记

学习地址:www.zhulaoshi.org


重定位实战


在SRAM中将0xD0020010重定位到0xD0024000,(重定位成功后,我们无法从结果看到什么现象)


思路

1.将链接地址设定为0xD0024000,

2.dnw下载地址设为0xD0020010,

3.代码执行时通过代码前段少量位置无关代码将整个代码搬移到0xD0024000,

4.使用一个长跳转ldr pc, =led_blink跳转到0xD0024000,完成重定位。


下面就是这节课涉及的汇编源文件,反汇编文件和链接脚本文件。

为了便于理解,先把一些关键点拿出来解释一下。

adr r0, _start  // adr加载时就叫短加载

这句伪指令,用于加载_start当前运行地址,下面是反汇编得到的结果,

d002401c: e24f0024 sub r0, pc, #36 ; 0x24


ldr r1, =_start // ldr加载时如果目标寄存器是pc就叫长跳转,如果目标寄存器是r1等就叫长加载

这句伪指令,用于加载_start的链接地址:0xd0024000,下面是反汇编得到的结果,

d0024020: e59f1048 ldr r1, [pc, #72] ; d0024070 <run_on_dram+0x10>

d0024070处的值是d0024000,即链接地址,

ps:这里的ARM是3级流水线,所以pc的值是当前地址的值往后数2个,

这里还有更细的讲解,开始有点脑袋不够用了,


长跳转:跳转到的地址和当前地址差异比较大,跳转的范围比较远。
ldr pc, =led_blink// ldr指令实现长跳转
bl led_blink // bl指令实现短跳转


ldr和adr都是伪指令,区别是ldr是长加载、adr是短加载。
重点:adr指令加载符号地址,加载的是运行时地址;ldr指令在加载符号地址时,加载的是链接地址。

#define WTCON		0xE2700000
#define SVC_STACK	0xD0037D80

.global _start
_start:

	ldr r0, =0x0
	ldr r1, =WTCON
	str r0, [r1]
	
	ldr sp, =SVC_STACK
	
	mrc p15,0,r0,c1,c0,0
	bic r0,r0,#(1<<12)
//	orr r0,r0,#(1<<12)
	mcr p15,0,r0,c1,c0,0

上面属于重定位代码部分,属于我们这里要分析讲解的内容

	adr r0, _start
	这里加载的是当前运行地址,也就是dnw下载时设定的0xd0020010
	
	ldr r1, =_start
	这里加载的是链接地址,也就是链接脚本开始处设定的0xd0024000
	
	ldr r2, = bss_start
	cmp r0, r1
	beq clean_bss
	
copy_loop:
	ldr r3, [r0], #4
	str r3, [r1], #4
	这里的两句有个相似的方面,
	这个相似的点就类似于C语言里面的这个特性,i++;
	以前呢,只是知道++i和i++的区别,但是没有体会到用法上的妙处,
	这里这样的用法,正好配合上后面的cmp比较语句,
	其次也加深了对i++这里后加的特性,
	开始只是知道++操作是在当前语句最后执行,
	这里由于分解成了汇编,所以看的更清楚了。
	
	
	cmp r1, r2
	bne copy_loop
	
clean_bss:
	ldr r0, =bss_start
	ldr r1, =bss_end
	这里的标号bss_start和bss_end能更好的帮助我理解link.lds链接脚本
	
	cmp r0, r1
	beq run_on_dram
	mov r2, #0
	
clear_loop:
	str r2, [r0], #4
	cmp r0, r1
	bne clear_loop
	
run_on_dram:
	ldr pc, =led_blink

	bl led_blink
	
	b .
copy代码的长度,有一次看错了,实际上没错,下次看的时候注意这里的提醒!

SECTIONS
{
	. = 0xd0024000;
	这里的地址就是我们希望链接的地址
	
	说一句无关上下,也有关上下的话,
	这里也可以理解为内存,从上往下,地址是在增加的,
	虽然我们并不知道增加的数值,不过我们也无需关系,这是编译器在负责。
	
	
	.text : {
		start.o
		* (.text)
	}
	这里要强调的是,start.o被安排在前面,后面用*代替的顺序不重要。
	
	.data : {
		* (.data)
	}
	这里要和下面的bss段联系下来讲,
	这里如果存储的有数据的话,就是非0的,
	知道了这一点,应该就能明白重定位代码中复制的功能,在什么情况下复制已经完成。
	
	bss_start = .;
	.bss : {
		* (.bss)
	}
	
	bss_end = .;
	这里的两个标号开始觉得长得有点怪,看了重定位代码后,想法改变了。
	
}


Makefile文件中改变了这一句

arm-linux-ld -Tlink.lds -o led.elf $^


下面是反汇编文件,反正是全部粘贴出来了,还有些讲不清楚,就把某些地方红色标记吧,下次看的方便些。

好像是因为地址无关指令占用了一些地址空间,所以在分析下面地址变化以及指令的时候,没很明白。

如果还是想懂得话,就看这节课的讲解。

led.elf:     file format elf32-littlearm


Disassembly of section .text:

d0024000 <_start>:
d0024000:	e59f0060 	ldr	r0, [pc, #96]	; d0024068 <run_on_dram+0x8>
d0024004:	e3a01000 	mov	r1, #0
d0024008:	e5801000 	str	r1, [r0]
d002400c:	e59fd058 	ldr	sp, [pc, #88]	; d002406c <run_on_dram+0xc>
d0024010:	ee110f10 	mrc	15, 0, r0, cr1, cr0, {0}
d0024014:	e3800a01 	orr	r0, r0, #4096	; 0x1000
d0024018:	ee010f10 	mcr	15, 0, r0, cr1, cr0, {0}
d002401c:	e24f0024 	sub	r0, pc, #36	; 0x24
d0024020:	e59f1048 	ldr	r1, [pc, #72]	; d0024070 <run_on_dram+0x10>
d0024024:	e59f2048 	ldr	r2, [pc, #72]	; d0024074 <run_on_dram+0x14>
d0024028:	e1500001 	cmp	r0, r1
d002402c:	0a000003 	beq	d0024040 <clean_bss>

<span style="background-color: rgb(255, 0, 0);">d0024030 <copy_loop>:</span>
d0024030:	e4903004 	ldr	r3, [r0], #4
d0024034:	e4813004 	str	r3, [r1], #4
d0024038:	e1510002 	cmp	r1, r2
d002403c:	1afffffb 	bne	d0024030 <copy_loop>

<span style="background-color: rgb(255, 0, 0);">d0024040 <clean_bss>:</span>
d0024040:	e59f002c 	ldr	r0, [pc, #44]	; d0024074 <run_on_dram+0x14>
d0024044:	e59f102c 	ldr	r1, [pc, #44]	; d0024078 <run_on_dram+0x18>
d0024048:	e1500001 	cmp	r0, r1
d002404c:	0a000003 	beq	d0024060 <run_on_dram>
d0024050:	e3a02000 	mov	r2, #0

<span style="background-color: rgb(255, 0, 0);">d0024054 <clear_loop>:</span>
d0024054:	e4802004 	str	r2, [r0], #4
d0024058:	e1500001 	cmp	r0, r1
d002405c:	1afffffc 	bne	d0024054 <clear_loop>

d0024060 <run_on_dram>:
d0024060:	e59ff014 	ldr	pc, [pc, #20]	; d002407c <run_on_dram+0x1c>
d0024064:	eafffffe 	b	d0024064 <run_on_dram+0x4>
d0024068:	e2700000 	rsbs	r0, r0, #0
d002406c:	d0037d80 	andle	r7, r3, r0, lsl #27
d0024070:	d0024000 	andle	r4, r2, r0
d0024074:	d0024128 	andle	r4, r2, r8, lsr #2
d0024078:	d0024128 	andle	r4, r2, r8, lsr #2
d002407c:	d002409c 	mulle	r2, ip, r0
d0024080:	00001a41 	andeq	r1, r0, r1, asr #20
d0024084:	61656100 	cmnvs	r5, r0, lsl #2
d0024088:	01006962 	tsteq	r0, r2, ror #18
d002408c:	00000010 	andeq	r0, r0, r0, lsl r0
d0024090:	45543505 	ldrbmi	r3, [r4, #-1285]	; 0x505
d0024094:	08040600 	stmdaeq	r4, {r9, sl}
d0024098:	00010901 	andeq	r0, r1, r1, lsl #18

d002409c <led_blink>:
d002409c:	e92d4800 	push	{fp, lr}
d00240a0:	e28db004 	add	fp, sp, #4
d00240a4:	e59f3028 	ldr	r3, [pc, #40]	; d00240d4 <led_blink+0x38>
d00240a8:	e59f2028 	ldr	r2, [pc, #40]	; d00240d8 <led_blink+0x3c>
d00240ac:	e5832000 	str	r2, [r3]
d00240b0:	e59f3024 	ldr	r3, [pc, #36]	; d00240dc <led_blink+0x40>
d00240b4:	e3a02000 	mov	r2, #0
d00240b8:	e5832000 	str	r2, [r3]
d00240bc:	eb000007 	bl	d00240e0 <delay>
d00240c0:	e59f3014 	ldr	r3, [pc, #20]	; d00240dc <led_blink+0x40>
d00240c4:	e3a02038 	mov	r2, #56	; 0x38
d00240c8:	e5832000 	str	r2, [r3]
d00240cc:	eb000003 	bl	d00240e0 <delay>
d00240d0:	eafffff6 	b	d00240b0 <led_blink+0x14>
d00240d4:	e0200240 	eor	r0, r0, r0, asr #4
d00240d8:	11111111 	tstne	r1, r1, lsl r1
d00240dc:	e0200244 	eor	r0, r0, r4, asr #4

d00240e0 <delay>:
d00240e0:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
d00240e4:	e28db000 	add	fp, sp, #0
d00240e8:	e24dd00c 	sub	sp, sp, #12
d00240ec:	e59f3030 	ldr	r3, [pc, #48]	; d0024124 <delay+0x44>
d00240f0:	e50b3008 	str	r3, [fp, #-8]
d00240f4:	e51b3008 	ldr	r3, [fp, #-8]
d00240f8:	e3530000 	cmp	r3, #0
d00240fc:	03a02000 	moveq	r2, #0
d0024100:	13a02001 	movne	r2, #1
d0024104:	e20220ff 	and	r2, r2, #255	; 0xff
d0024108:	e2433001 	sub	r3, r3, #1
d002410c:	e50b3008 	str	r3, [fp, #-8]
d0024110:	e3520000 	cmp	r2, #0
d0024114:	1afffff6 	bne	d00240f4 <delay+0x14>
d0024118:	e28bd000 	add	sp, fp, #0
d002411c:	e8bd0800 	pop	{fp}
d0024120:	e12fff1e 	bx	lr
d0024124:	000dbba0 	andeq	fp, sp, r0, lsr #23

Disassembly of section .comment:

00000000 <.comment>:
   0:	43434700 	movtmi	r4, #14080	; 0x3700
   4:	5328203a 	teqpl	r8, #58	; 0x3a
   8:	6372756f 	cmnvs	r2, #465567744	; 0x1bc00000
   c:	20797265 	rsbscs	r7, r9, r5, ror #4
  10:	202b2b47 	eorcs	r2, fp, r7, asr #22
  14:	6574694c 	ldrbvs	r6, [r4, #-2380]!	; 0x94c
  18:	30303220 	eorscc	r3, r0, r0, lsr #4
  1c:	2d337139 	ldfcss	f7, [r3, #-228]!	; 0xffffff1c
  20:	20293736 	eorcs	r3, r9, r6, lsr r7
  24:	2e342e34 	mrccs	14, 1, r2, cr4, cr4, {1}
  28:	Address 0x00000028 is out of bounds.


Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:	00002641 	andeq	r2, r0, r1, asr #12
   4:	61656100 	cmnvs	r5, r0, lsl #2
   8:	01006962 	tsteq	r0, r2, ror #18
   c:	0000001c 	andeq	r0, r0, ip, lsl r0
  10:	45543505 	ldrbmi	r3, [r4, #-1285]	; 0x505
  14:	08040600 	stmdaeq	r4, {r9, sl}
  18:	12010901 	andne	r0, r1, #16384	; 0x4000
  1c:	15011404 	strne	r1, [r1, #-1028]	; 0x404
  20:	18031701 	stmdane	r3, {r0, r8, r9, sl, ip}
  24:	Address 0x00000024 is out of bounds.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值