zoukankan      html  css  js  c++  java
  • arm汇编中LDR,MOV,STR区别

    一,LDR和STR的区别

    转载:https://www.cnblogs.com/Rainingday/p/7422670.html

    在ARM架构下,  数据从内存到CPU之间的移动只能通过LDR/STR指令来完成.而MOV只能在寄存器之间移动数据,或者把立即数移动到寄存器中,并且数据的长度不能超过8位

    LDR,STR 的第一操作数是目标寄存器,第二操作数是内存地址,
    LDR 内存 --> 寄存器;
    STR 寄存器 --> 内存
    内存的表示方式有:立即数,寄存器,或寄存器加偏移,立即数:内存的物理位置,前面加个#,如0x56000050
    寄存器,加个[],如[r1],偏移的话[r1,r2],或者[r1,#4],[r1,LSL #4]等,都差不多,就是把寄存器里的数当成地址。

    以下是具体的应用例子:

         1.  LDR   r0,=label      用于加载立即数或一个地址值到指定寄存器中

       1.1  如果label是立即数:  LDR r0,=0X123           ;将0X123存入r0中

       1.2  如果name是个标识符:  LDR   r0,=label_1    ;将label_1所指向的地址值存入r0中

    这是一条伪指令:表示把一个地址写到某寄存器中

    比如:ldr r0, =0x12345678这样,就把0x12345678这个地址写到r0中了。所以,ldr伪指令和mov是比较相似的。只不过mov指令限制了立即数的长度为8位,也就是不能超过512。而ldr伪指令没有这个限制。如果使用ldr伪指令时,后面跟的立即数没有超过8位,那么在实际汇编的时候该ldr伪指令是被转换为mov指令的。

    2.   LDR       r0,[r1]   ;将R1中的值存到r0中

    3.   LDR       r1,[r2,#16]    ;将(r2+16)地址中的内容存到r1中

    4.   LDR       r1,[r2],#4    ;将r2地址中的内容存到r1中,同时r2=r2+4

    a.  STR   r1,[r2]        ; 将r1中的值存到r2所指定的地址中

    b.  STR   r1,[r2,#4]   ;将r1中的值存到r2+4所指定的地址中

    c.   STR   r1,[r2],#4  ;将r1中的值存到r2所指定的地址中, 同时r2=r2+4

    二,LDR和MOV区别

    转载:https://www.cnblogs.com/xmphoenix/p/4370081.html

    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用起来比较麻烦,因为有些数不那么容易看出来是否合法。

  • 相关阅读:
    匿名字段和内嵌结构体
    Go函数式编程的闭包和装饰器设计模式
    理解Golang中defer的使用
    Go匿名函数及闭包
    GO语言学习笔记-缓冲区Channels和线程池
    你需要知道的关于Neutron的一切事情
    []T 还是 []*T, 这是一个问题
    Golang 方法接收者为值与指针的区别
    第九章 python语法入门之与用户交互、运算符
    第八章 python语法入门之垃圾回收机制
  • 原文地址:https://www.cnblogs.com/zhiminyu/p/15629073.html
Copyright © 2011-2022 走看看