现在的位置: 首页 > 综合 > 正文

LDR 、ADR介绍

2014年09月05日 ⁄ 综合 ⁄ 共 2060字 ⁄ 字号 评论关闭

LDR 、ADR介绍  

请教:
(1)LDR R1,= 0x12345678 ;加载 32 位立即数
         LDR R1,0x12345678
有什么不相同啊?
一般在什么情况下用 LDR R1,= 0x12345678 ?
在什么情况下用 LDR R1,0x12345678 ?

(2)LDR R0,=LED_TAB ;加载标号地址
         LDR R0,LED_TAB
有什么不相同啊?
一般在什么情况下用 LDR R0,=LED_TAB ?
在什么情况下用 LDR R0,LED_TAB ?

====================================================

答:
1. 没有“LDR R1,0x12345678 ”。
2. 以下两条指令是一样的,都被称为“伪指令”,就是说编译器会把这条指令替换成其他合适的指令。
LDR R1, =0x12345678
LDR R0, =LED_TAB
如果这些数值不太复杂,那么就会用mov指令代替,比如:
ldr r1, =0x00
在编译时就会变成:
mov r1, #0x00

如果这些数值很复杂,那么编译时,这个数值会被保存在某个地方,然后使用读内存的指令进行读取,比如:
LDR R1, =0x12345678
在编译时变成:
ldr r1, [pc, xxxxx] // 这个xxx与pc相加,刚好就是some_locate的地址──编译器会帮你做好这一切
some_locate: .word 0x12345678

3. 你说“LDR R0,=LED_TAB ;加载标号地址 ”,没错,
LED_TAB是个地址标号,就是一个数值而已,编译器连接程序时会确定它的值,如果它很简单,就会使用mov指令赋值;如果很复杂,就存在某个地址,然后用读内存的指令读出。

4. LDR R0,LED_TAB
没有“=”号,它表示“读内存”.
比如:
LDR R0,LED_TAB
LDR R1, =LED_TAB
LED_TAB: .work 0x12345678

R0的值是0x12345678,R1的值是LED_TAB标号值,就是0x12345678在内存中存放的地址

 

 

adr是将基于PC相对偏移的地址值或基于寄存器相对地址值读取的为指令,而ldr用于加载32为立即数或一个地址到指定的寄存器中。到这儿就会看到其中的区别了。如果在程序中想加载某个函数或者某个在联接时候指定的地址时请使用adr,例如在lds中需要重新定位的地址。当加载32为的立即数或外部地址时请用ldr。
下面是   
    ldr r0,_start
    ldr r1,_TEXT_BASE
    ldr r2,_armboot_start
    ldr r3,_bss_start
    sub r2,r3,r2
    add r2,r2,r0

    adr r0,_start
    ldr r1,_TEXT_BASE
    adr r2,_armboot_start
    adr r3,_bss_start
    sub r2,r3,r2
    add r2,r2,r0
两个片段的反汇编代码
80000068:    e51f0070     ldr    r0, [pc, #ffffff90]    ; 80000000 <_start>
8000006c:    e51f1054     ldr    r1, [pc, #ffffffac]    ; 80000020 <_TEXT_BASE>
80000070:    e51f2054     ldr    r2, [pc, #ffffffac]    ; 80000024 <_armboot_start>
80000074:    e51f3054     ldr    r3, [pc, #ffffffac]    ; 80000028 <_bss_start>
80000078:    e0432002     sub    r2, r3, r2
8000007c:    e0822000     add    r2, r2, r0

--------------------------------------------------------------------------
80000068:    e24f0070     sub    r0, pc, #112    ; 0x70
8000006c:    e24f1054     sub    r1, pc, #84    ; 0x54
80000070:    e24f2054     sub    r2, pc, #84    ; 0x54
80000074:    e24f3054     sub    r3, pc, #84    ; 0x54
80000078:    e0432002     sub    r2, r3, r2
8000007c:    e0822000     add    r2, r2, r0

由于ldr是读取的32为地址,因此会自动用fffff来填充,可是用PC相减的时候就不知道减到哪儿去了。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lemon_fantasy/archive/2009/01/09/3740475.aspx

抱歉!评论已关闭.