您的位置:首页 > 其它

ARM汇编中ldr与adr的区别(转)

2014-05-06 17:32 375 查看
ldr与adr的区别

转自:http://coon.blogbus.com/logs/2738861.html

ldr
r0, _start

adr
r0, _start

ldr
r0, =_start

nop

mov
pc, lr
_start:

nop

编译的时候设置 RO 为 0x0c008000

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
0c008000
<_start-0x14>:
c008000:
e59f000c
ldr
r0, [pc, #12]
; c008014
<_start>
c008004:
e28f0008
add
r0, pc, #8
; 0x8
c008008:
e59f0008
ldr
r0, [pc, #8]
; c008018
<_start+0x4>
c00800c:
e1a00000
nop

(mov r0,r0)
c008010:
e1a0f00e
mov
pc, lr
0c008014
<_start>:
c008014:
e1a00000
nop

(mov r0,r0)
c008018:
0c008014
stceq
0, cr8, [r0], -#80
分析:
ldr
r0, _start
从内存地址 _start 的地方把值读入。执行这个后,r0 =
0xe1a00000
adr
r0, _start
取得 _start 的地址到
r0,但是请看反编译的结果,它是与位置无关的。其实取得的时相对的位置。例如这段代码在 0x0c008000 运行,那么 adr r0,
_start 得到 r0 = 0x0c008014;如果在地址 0 运行,就是 0x00000014 了。
ldr
r0, =_start
这个取得标号 _start 的绝对地址。这个绝对地址是在 link
的时候确定的。看上去这只是一个指令,但是它要占用 2 个 32bit 的空间,一条是指令,另一条是 _start
的数据(因为在编译的时候不能确定 _start 的值,而且也不能用 mov 指令来给 r0 赋一个 32bit
的常量,所以需要多出一个空间存放 _start 的真正数据,在这里就是 0x0c008014)。
因此可以看出,这个是绝对的寻址,不管这段代码在什么地方运行,它的结果都是
r0 = 0x0c008014
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: