ARM 如何实现绝对地址的跳转

基于 b跳转指令,ldr伪指令,ldr加载指令分析

有以下场景需用到

1.实现从Stepingstone中执行部分指令后,需跳转到SDRAM中执行,前提是必须先将NAND FLASH中代码copy到SDRAM,然后才能跳转到SDRAM去执行。跳转到SDRAM 需使用LDR伪指令LDR PC,=SDRAM 来实现

分析:

b指令是相对跳转指令,可以看到起反汇编代码是完全一样的,它依赖于当前PC寄存器的值,不管此代码链接地址如何,b指令都可以跳转到正确位置,这类指令称为位置无关指令

ldr pc,=labr 伪指令,从反汇编代码可以看出,是从内存的某个位置读出数据,并赋给pc寄存器,其中存放的值依赖于链接脚本文件的链接地址。是绝对跳转指令。

2.在SDRAM中实现中断的调试,必须将中断向量也在0x00000000位置放置,让其跳转到SDRAM对应位置

Vectors         
		ldr     PC, Reset_Addr     ;@0x00复位    
		ldr     PC, Undef_Addr	;@ 0x04: 未定义指令中止模式的向量地址
		ldr     PC, SWI_Addr		;@ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
		ldr     PC, PAbt_Addr		;@ 0x0c: 指令预取终止导致的异常的向量地址
		ldr     PC, DAbt_Addr		;@ 0x10: 数据访问终止导致的异常的向量地址
		nop	 					;@ 0x14: 保留
		ldr     PC, IRQ_Addr		;@ 0x18: 中断模式的向量地址
		ldr 	   PC, FIQ_Addr  	;@ 0x1c: 快中断模式的向量地址
Reset_Addr      	DCD     Reset_Handler
Undef_Addr      DCD     Undef_Handler
SWI_Addr       	DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                	nop
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler
Reset_Handler                
    <…对应指令代码 …>
Undef_Handler	b	Undef_Handler	;未用到,可以用此指令保留
SWI_Handler		b	SWI_Handler		;未用到,可以用此指令保留
PAbt_Handler		b	PAbt_Handler		;未用到,可以用此指令保留
DAbt_Handler		b	DAbt_Handler		;未用到,可以用此指令保留
FIQ_Handler		b	FIQ_Handler		;未用到,可以用此指令保留
IRQ_Handler
    	sub lr, lr, #4                  ;@ 计算返回地址
    	stmdb   sp!,    { r0-r12,lr }   ;@ 保存使用到的寄存器
                                    ;@ 注意,此时的sp是中断模式的sp
                                     ;@ 初始值是上面设置的3072
		ldr lr , =int_return
    	ldr pc, =EINT_Handle            ;@ 调用中断服务函数,在interrupt.c中
int_return			;因为ldr跳转不能够把下一条指令的地址保存到lr,所以需要在跳转之前字写指令保存起来,
    ldmia   sp!,    { r0-r12,pc }^ 	 ;@ 中断返回, ^表示将spsr的值复制到cpsr
    END

使用ldr加载指令(not ldr伪指令)实现绝对地址跳转

hander标号依赖于链接脚本地址的设定,将hander地址放在标号为step3标号的内存中,从而达到实现绝对地址跳转的目的。

+++++++++++link2.s+++++++++

.text

.global _start

_start: b step1

step1: ldr pc,=step2

step2: ldr pc,step3

step3: .long hander

hander: b step4

step4: b step4

+++++++++++Makefile++++++++++++++

link2: link2.s

arm-linux-gcc -c -o link2.o link2.s

arm-linux-ld -Ttext 0x00000000 link2.o -o link2_elf_0x00000000

arm-linux-ld -Ttext 0x30000000 link2.o -o link2_elf_0x30000000

arm-linux-objdump -D link2_elf_0x00000000 > link2_0x00000000_dis

arm-linux-objdump -D link2_elf_0x30000000 > link2_0x30000000_dis

clean :

rm -f *.o













link2_elf_0x30000000:file format elf32-littlearm

Disassembly of section .text:

30000000 <_start>:

30000000: eaffffff b 30000004 <step1>

30000004 <step1>:

30000004: e59ff00c ldr pc, [pc, #12]; 30000018 <step4+0x4>

30000008 <step2>:

30000008: e51ff004 ldr pc, [pc, #-4] ; 3000000c <step3>

3000000c <step3>:

3000000c: 30000010 .word 0x30000010

30000010 <hander>:

30000010: eaffffff b 30000014 <step4>

30000014 <step4>:

30000014: eafffffe b 30000014 <step4>

30000018: 30000008 .word 0x30000008

link2_elf_0x00000000:file format elf32-littlearm

Disassembly of section .text:

00000000 <_start>:

0: eaffffff b 4 <step1>

00000004 <step1>:

4: e59ff00c ldr pc, [pc, #12] ; 18 <step4+0x4>

00000008 <step2>:

8: e51ff004 ldr pc, [pc, #-4] ; c <step3>

0000000c <step3>:

c: 00000010 .word 0x00000010

00000010 <hander>:

10: eaffffff b 14 <step4>

00000014 <step4>:

14: eafffffe b 14 <step4>

18: 00000008 .word 0x00000008


















和此内容相关的例子,可参考此代码(直接copy此代码到MDK工程,生成bin文件,运行在mini2440板子上):

http://my.csdn.net/wfq0624/code/detail/7750


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值