ARM指令LDR和ARM伪指令LDR

来源:互联网 发布:山东大学网络助学 编辑:程序博客网 时间:2024/04/27 14:14
LDR伪指令的形式是“LDR Rn,=expr”,例:
COUNT EQU 0x40003100 ……
LDR R1,=COUNT
MOV R0,#0
STR R0,[R1]
COUNT是我们定义的一个变量,地址为0x40003100。这种定义方法在汇编语言中是很常见的。
LDR R1,=COUNT是将COUNT这个变量的地址,也就是0x40003100放到R1中。
MOV R0,#0是将立即数0放到R0中。
最后一句STR R0,[R1]是一个典型的存储指令,将R0中的值放到以R1中的值为地址的存储单元去。
实际就是将0放到地址为0x40003100的存储单元中去。可见这三条指令是为了完成对变量COUNT赋值。
用三条指令来完成对一个变量的赋值,看起来有点不太舒服。这可能跟ARM的采用RISC有关。
下面还有一个例子 ;将COUNT的值赋给R0
LDR R1,=COUNT
LDR R0,[R1]
这条指令实际上会编译成一条LDR指令和一条 DCD伪指令。
 
 
ARM指令LDR和ARM伪指令LDR有什么区别
伪指令LDR{cond} register, ={expr|label-expr}
expr为32为常量。编译器根据expr的取值情况来处理这条伪指令:
1、当expr表示的地址没有超过mov或mvn指令中地址的取值范围时,编译器用合适的mov指令或mvn指令代替该LDR伪指令。
2、当expr表示的地址超过了mov或mvn指令中地址的取值范围时,编译器将该常数放在缓冲区中,同时用一条基于PC的LDR指令读取该常数。
由于arm是risc精简指令集,指令都是32位的,在编码中操作码,目标和源寄存器是要占掉32位一部分,
所以一条指令里面不可能存一个32位的立即数,所以arm提供了一条伪指令来完成一条指令load一个32位的立即数。
方法是在这条指令附近放要load的值,再利用当前的pc+偏移load这个数,注意ldr的原来的意义是将内存的某个值load到寄存器里面。
比如:
ldr r0, =0x5000010
经过arm的assembler的翻译实际上就是:
ldr r0, [pc+#0x4] ;;指令是4byte 32位,就是将内存中下一个word放到r0中
0x500010 ;;这个地方放的是数值。这里,0x4是在它立即数的范围内的
 
arm指令中mov和ldr的区别
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指令不是一个同东西。
 

ARM伪指令之地址读取:ADR ADRL LDR
1、ADR伪指令--- 小范围的地址读取
     ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
ADR伪指令格式 :ADR{cond}   register, expr
地址表达式expr的取值范围:
    当地址值是字节对齐时,其取指范围为: +255 ~ 255B;
    当地址值是字对齐时,其取指范围为:   -1020 ~ 1020B;
2、ADRL伪指令----中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。
ADRL伪指令格式:ADRL{cond}   register, expr
地址表达式expr的取值范围:
    当地址值是字节对齐时,其取指范围为: -64K~64K;
   当地址值是字对齐时,其取指范围为:   -256K~256K;
3、LDR伪指令-----大范围的地址读取
LDR 伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或 MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。
0 0
原创粉丝点击