刘帅嵌入式系统-字及无符号字节的Load/Store指令寻址方式

文章转自:https://blog.csdn.net/qqliyunpeng/article/details/48791311 

    一、简介:

    ARM体系架构中,是不允许cpu直接访问内存单元。

    为了解决访问内存单元的需要,使用寄存器作为中继,内存和寄存器通过load/store指令交互,cpu在访问寄存器。

    内存单元 和  寄存器 直接的数据交互。

单寄存器指令  ldr  str多寄存器指令  ldm  stm交互指令      swp

二、单寄存器指令:

(1)指令功能:1个寄存器和1个内存单元数据交互。

         ldr   内存单元 ----> 寄存器   (l是left)红字的部分只适用于单寄存器指令,多寄存器指令正好相反

         str   寄存器   ----> 内存单元(t是to)

(2)语法格式 :

        LDR{<cond>}{<size>} Rd, <address>

        STR{<cond>}{<size>} Rd, <address>

      {} :可选

           {<cond>} :条件码

           {<size>}  :传送单元大小

            Rd       :寄存器

           <address> :内存地址

(3)<address> :

        1 --- 标号寻址 (地址的助记符)

              str r1,val      @ *(val) = r1

              val:

                   .word 0x11223344

        2--- 寄存器间接寻址

           mov r0,#0x41000000

           str r1,[r0]    @ *(r0) = r1

        3--- 基址变址寻址

          mov r0,#0x41000000

          str r1,[r0,#4]    @ *(r0+4) = r1

(4)基址变址寻址偏移量的三种形式 :

        1--- 立即数        str r1,[r0,#4]

     

        2--- 寄存器         mov r2,#4

                                str r1,[r0,r2]

        3--- 寄存器移位  mov r2,#1

                                str r1,[r0,r2,lsl #2]

(5)基址变址的三种方式 :

        1-- 前索引    str r1,[r0,#4]    @ *(r0+4) = r1  类似  *(p+1)

        2-- 自动索引  str r1,[r0,#4]!   @ r0 =r0+4  *(r0)=r1 类似  *(++p)  p=p+1、*p

        3-- 后索引    str r1,[r0],#4   @  *(r0)=r1  r0 =r0+4  类似  *p++  

 *p、p=p+1

(6)ldr指令和ldr伪指令的区别 :--易混淆部分举例

    第一组:

        ldr r0,=0xff     @ r0=0xff

        mov r1,#0xff     @ r0=*(0xff)

            ldr r0,[r1]

    第二组:

       ldr r0, =val    @ r0 =val地址

        ldr r0,val       @ r0 =*(val的地址)

     val

        .word 0x41000000

(7){<size>}  :传送单元大小

     指定指令访问内存单元中的几个字节 4个、2个、1个

         4个  :默认

         2个  :H

         1个  :B

    低位优先使用,高位补0

三、多寄存器指令 :

(1)指令功能:多个寄存器和多个内存单元数据交互。

         ldm   内存块       ---给-> 多个寄存器  

         stm   多个寄存器 ---给-> 内存块

(2)指令的格式:

    <LDM>{<cond>}<addressing_mode> Rb{!}, <寄存器 list>

    <STM>{<cond>}<addressing_mode> Rb{!}, <寄存器 list>

   {<cond>}          :条件码(可选)

   <addressing_mode> :地址模式

        Rb           : 内存块的首地址

        {!}            :是否更新基址

   <寄存器 list>     :寄存器列表

(3) <addressing_mode> :地址模式

       I --- 加

       D --- 减

       A --- 后 :地址后操作

       B --- 先 :地址先操作

       IA --- 先操作数据,再操作地址(加)

       IB --- 先操作地址(加),再操作数据

       DA --- 先操作数据,再操作地址(减)

       DB --- 先操作地址(减),再操作数据

(4) <寄存器 list>     :寄存器列表

      寄存器列表写法:

      1-- 罗列  

              {r1,r2,r3,r4,r7}

      2-- 连续的寄存器可以缩写

              {r1-r4,r7}

例子:

    mov r4,#0x41000000

    stmia r4!,{r0-r3}

    注意:

        存储顺序与寄存器列表的顺序无关,永远都是小号寄存器对应小地址。

        大括号中无论怎么排列,都是r0放在0x41000000地址上

四、多寄存器指令对栈的操作 :

(1) ldm  --  出栈   --- pop

           stm  --  压栈   --- push

(2)栈操作的地址模式

      F  满  --- sp指向的空间,有数据

      E  空  --- sp指向的空间,无数据

      D  减  --- 栈向地址减小的方向增长

      A  增  --- 栈向地址增大的方向增长

(3)ARM体系结构下,栈都是满减的栈

     满减栈(fd)

      stmfd -- 压栈 --- (--i) --相当于地址先减1,再在地址上放数据

            这里说明在压栈的时候地址指针sp指向了栈顶的上一个元素

      ldmfd -- 出栈 --- (i++) --相当于先将地址上的数据取走,地址再加

五、ARM的寻址方式:

8种:

立即数寻址

寄存器寻址

寄存器间接寻址

寄存器移位寻址

基址变址寻址

多寄存器寻址

相对寻址

堆栈寻址

猜你喜欢

转载自blog.csdn.net/shuai532209720/article/details/88627571