【转】LDR 和MOV 指令区别

最近在学习ARM的使用,此篇文章要特别注意MOV和ldr/str指令的区别

以下正文


ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。
比如想把数据从内存中某处读取到寄存器中,只能使用ldr 比如: ldr r0, 0x12345678
就是把0x12345678这个地址中的值存放到r0中。
而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中,这个和x86这种CISC架构的芯片区别最大的地方。
x86中没有ldr这种指令,因为x86的mov指令可以将数据从内存中移动到寄存器中。

另外还有一个就是ldr伪指令,虽然ldr伪指令和ARM的ldr指令很像,但是作用不太一样。ldr伪指令可以在立即数前加上=,以表示把一个地址写到某寄存器中,比如:
ldr r0, =0x12345678
这样,就把0x12345678这个地址写到r0中了。所以,ldr伪指令和mov是比较相似的。只不过mov指令限制了立即数的长度为8位,也就是不能超过512。而ldr伪指令没有这个限制。如果使用ldr伪指令时,后面跟的立即数没有超过8位,那么在实际汇编的时候该ldr伪指令是被转换为mov指令的。

ldr伪指令和ldr指令不是一个同东西


LDR指令的格式:

LDR{条件} 目的寄存器 <存储器地址>

作用:将 存储器地址 所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中。

LDR指令的寻址方式比较灵活,实例如下:

LDR R0,[R1]
;将存储器地址为R1的字数据读入寄存器R0。

LDR R0,[R1,R2]
;将存储器地址为R1+R2的字数据读入寄存器R0。

LDR R0,[R1,#8]
;将存储器地址为R1+8的字数据读入寄存器R0。

LDR R0,[R1],R2
;将存储器地址为R1的字数据读入寄存器R0,并将R1+R2的值存入R1。

LDR R0,[R1],#8
;将存储器地址为R1的字数据读入寄存器R0,并将R1+8的值存入R1。

LDR R0,[R1,R2]!
;将存储器地址为R1+R2的字数据读入寄存器R0,并将R1+R2的值存入R1。

LDR R0,[R1,LSL #3]
;将存储器地址为R1*8的字数据读入寄存器R0。

LDR R0,[R1,R2,LSL #2]
;将存储器地址为R1+R2*4的字数据读入寄存器R0。

LDR R0,[R1,,R2,LSL #2]!
;将存储器地址为R1+R2*4的字数据读入寄存器R0,并将R1+R2*4的值存入R1。

LDR R0,[R1],R2,LSL #2
;将存储器地址为R1的字数据读入寄存器R0,并将R1+R2*4的值存入R1。

LDR R0,Label
;Label为程序标号,Label必须是当前指令的-4~4KB范围内。

要注意的是

LDR Rd,[Rn],#0x04
;这里Rd不允许是R15。

另外LDRB 的指令格式与LDR相似,只不过它是将存储器地址中的8位(1个字节)读到目的寄存器中。

LDRH的指令格式也与LDR相似,它是将内存中的16位(半字)读到目的寄存器中。

LDR R0,=0xff

这里的LDR不是arm指令,而是伪指令。这个时候与MOVE很相似,只不过MOV指令后的立即数是有限制的。这个立即数必须是0X00-OXFF范围内的数经过偶数次右移得到的数,所以MOV用起来比较麻烦,因为有些数不那么容易看出来是否合法。


原文地址:http://www.cnblogs.com/xmphoenix/p/4370081.html

相关文章
相关标签/搜索