首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

如何实现绝对地址的跳转

如何实现绝对地址的跳转

如何实现绝对地址的跳转基于
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
继承事业,薪火相传
返回列表