Chinaunix首页 | 论坛 | 博客
  • 博客访问: 850920
  • 博文数量: 213
  • 博客积分: 5048
  • 博客等级: 大校
  • 技术积分: 1883
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-14 10:14
文章分类

全部博文(213)

文章存档

2011年(4)

2010年(55)

2009年(47)

2008年(107)

我的朋友

分类: 嵌入式

2010-01-07 23:06:46

arm汇编的跳转指令无非是b和ldr。但是如果没有足够理解,别人灵活的用一下你就犯晕了。
首先我们要知道两者的两个本质区别:
1、b是位置无关的,ldr不是位置无关的。
2、b的范围只能是+—32MB,而ldr是4GB。
 
在arm的启动汇编的中断向量表是必然用跳转指令的,但是就是这里也有很多实现形式:
方式1:
                B           InitReset           ; 0x00 Reset handler
undefvec:
                B           undefvec            ; 0x04 Undefined Instruction
swivec:
                B           swivec              ; 0x08 Software Interrupt
pabtvec:
                B           pabtvec             ; 0x0C Prefetch Abort
dabtvec:
                B           dabtvec             ; 0x10 Data Abort
rsvdvec:
                B           rsvdvec             ; 0x14 reserved
irqvec:
                B           IRQ_Handler_Entry   ; 0x18 IRQ
这个我很容易理解,实现的标号油InitReset和IRQ_Handler_Entry,其他没有实现的在原地跳转。
方式二:
        LDR     pc, =resetHandler        ; Reset
        LDR     pc, Undefined_Addr       ; Undefined instructions
        LDR     pc, SWI_Addr             ; Software interrupt (SWI/SYS)
        LDR     pc, Prefetch_Addr        ; Prefetch abort
        LDR     pc, Abort_Addr           ; Data abort
        B       .                        ; RESERVED
        LDR     pc, =irqHandler          ; IRQ
        LDR     pc, FIQ_Addr             ; FIQ
  LDR PC,[PC,#0x18]
Undefined_Addr: DCD   Undefined_Handler
SWI_Addr:       DCD   SWI_Handler
Prefetch_Addr:  DCD   Prefetch_Handler
Abort_Addr:     DCD   Abort_Handler
FIQ_Addr:       DCD   FIQ_Handler
我们注意到两种ldr
一种LDR PC,=label,这时把LDR当做伪指令,他要被翻译成:
LDR PC,[PC,offset_to_label2]
label2:DCD resetHandler
这种label是在程序中标记的了,如resetHandler和irqHandler
还有一种LDR PC,label,这时直接把label地址内存内容copy到PC中
这种label都是 label:DCD label2 ,这些label2可以在任何地方实现
 
我们来理解b和ldr两者的不同
1,b是位置无关,因为他的跳转都是相对PC来的,而ldr不是位置无关的,因为他的跳转是根据DCD里面的值,这个值是连接的时候确定的,他是跟连接地址有关的
2,b的范围只能是32M,是因为指令里面给偏移的空间只有24bit,而ldr是一个32bit的DCD,所以他是32bit的
 
注意:像上面方式二
LDR     pc, =resetHandler        ; Reset
resetHandler:
 ....
 ....
如果运行地址是0,那么LDR     pc, =resetHandler还在以基址为0的空间运行
但是执行完了,假设装载地址是0x3000000,所以resetHandler的基址不是0,而是0x30000000
所以resetHandler标号以后的指令应该存在以0x3000000为基址的空间,pc跳过去了
这种技巧在at91的remap模式经常用到
阅读(1705) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~