讲的比较好的一篇帖子,ADR和LDR区别的比较清除:
Load/Store指令
ARM属于RISC指令集,CPU无法对内存的数据进行直接操作,只能通过Load/Store指令来实现:当我们需要对内存中的数据进行操作时,首先将这个数据从内存中加载到寄存器,在寄存器中进行数据处理,最后将结果重新存储到内存中。使用指令:
LDR X1,[X0] //将x0的值作为地址,将该地址的数据保存到寄存器x1
LDR X1,LOOP //将LOOP地址上的数据送给X1
STR X1,[X0] //将x0的值作为地址,把X1寄存器的值存储到这个地址
ARM伪指令
常见的伪指令有:ADR、LDR、NOP,他们的用法:
ADR X0,LOOP //将标号LOOP的地址保存在X0中
LDR X0,=0x08000000 //将内存地址0x08000000赋值给x0
NOP //空操作=mov x0,x0
LDR伪指令
LDR伪指令的操作数前一般会有一个"="来表示这是一个伪指令,常用来传送比较长的数据,比如向X0传送64位地址。LDR伪指令在编译器处理时翻译成标准的汇编指令LDR + 文字池的形式。如:
LDR X0,=0x08030000
//被编译器翻译成:
LDR X0,[PC,#OFFSET]
。。。。。。。。。。。
DCD 0x08030000
编译器会自动为0x08030000分配到文字池中,然后计算出LDR伪指令到文字池数据的偏移,然后利用相对寻址传送到x0中。
ADR伪指令
ADR伪指令和LDR伪指令相似,都是加载一个地址到寄存器。不同的是ADR伪指令通常被编译器翻译成ADD指令,如:
ADR X0,LOOP
..........
LOOP:
B LOOP
//被编译器翻译成:
OFFSET=LOOP-(PC-8)
ADD X0,PC,#OFFSET
编译器先计算出ADR到LOOP的编译,然后使用ADD指令把地址传送到X0。
ADR伪指令和LDR伪指令的使用区别:
- LDR伪指令主要来操作外部设备寄存器;而ADR主要通过相对寻址,生成与位置无关的代码,只要标号的位置不变,就可以与位置无关。
- LDR伪指令使用绝对寻址,ADR伪指令使用相对寻址。
- LDR伪指令使用的地址范围【0-32GB】,ADR伪指令要求当前指令和标号必须在同一个段中,地址编译范围较小。