LDR与ADR伪指令的区别

来源:互联网 发布:潍坊行知学校怎么样 编辑:程序博客网 时间:2024/05/16 07:00

在学习ARM汇编指令的时候,经常会使用到ldr与adr两条指令,相信大部分初学的人曾经都对这两个命令产生过疑惑。

其实这两条指令都是伪指令:

  • ldr指令是大范围的地址读取伪指令,相对于PC寄存器或其他寄存器的大范围跳转;
  • adr指令是小范围的地址读取伪指令,相对于PC寄存器或其他寄存器的小范围跳转。

要想清楚的说明这两条指令的区别,还是得从实际的例子中来解释,空谈泛泛,难以实际掌握。

    ldr r0, _start    nop    nop    adr r0, _start    nop    nop    ldr r0, =_start    nop    nop_start:    nop

反汇编后的结果如下:

1   0x00000000: e59f001c ... LDR r0, [pc, #28]; [0x24]=e1a000002   0x00000004: e1a00000 ... MOV r0, r03   0x00000008: e1a00000 ... MOV r0, r04   0x0000000c: e28f0010 ... ADD r0, pc, 0x10; r0=x000000245   0x00000010: e1a00000 ... MOV r0, r0 6   0x00000014: e1a00000 ... MOV r0, r07   0x00000018: e59f0008 ... LDR r0, [pc, #8]; [0x28]=000000248   0x0000001c: e1a00000 ... MOV r0, r09   0x00000020: e1a00000 ... MOV r0, r0_start:10  0x00000024: e1a00000 ... MOV r0, r0    $d  存放_start地址值11  0x00000028: 00000024 ... DCD 36

第一行,寄存器间接寻址,获取_start的地址,此时,r0=0xe1a00000.
第四行,此时,r0=0x00000024.
第七行,取得标号_start的绝对地址,这个绝对地址是在link的时候确定的,看上去这只是一条指令,但是它要占用2个32bit的空间,一条是指令,另一条是_start的数据。因为在编译的时候不能够确定_start的值,而且也不能够用mov指令来给r0赋一个32bit的常量,所以需要多出一个空间来存放_start的真正数据,在这里就是0x00000024,由此可以看出,这个是绝对寻址,不管代码在什么地方运行,它的结果都是r0=0x00000024.

1 0
原创粉丝点击