ARM处理器的九种寻址方式

ARM 127浏览

1.立即数寻址

             数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数 

             示例: MOV R0,#255    ;0-255 都是立即数(在汇编中;就是注释符)该条指令的作用就是将立即数255放入寄存器R0中

              关于立即数的问题:

               a.立即数必须可以通过某个8位数据循环右移得到!

               b.立即数的判断方法步骤:

                       1、将数据转化为二进制数据 从低到高4位一组 最高位不够的直接补0
                       2、数1的个数 如果 大于8个 一定不是立即数
                       3、如果下雨八个 并且 数据中存在连续的24个0 循环左移偶数位使其高位全为0
                       4、找到最高位的1 去掉 前面偶数个0 
                       5、找到最低位的1 去掉 后面偶数个0
                       6、剩下的数据如果小于8位 那么就是一个立即数 否则不是

2.寄存器直接寻址

         示例:MOVS R0,R1  ;该条指令的作用相当于R0= R1,即将寄存器R1中的内容放入寄存器R0中

3.寄存器间接寻址

       将寄存器中的数据作为主存储器中的地址,然后将这个地址中的值加载到 操作数中

       示例:MOV R0,#0x2000 0000
                  ADD R3, R1,[R0] ; 此时将加载R0所存储地址所指向的内存中的的值加上寄存器R1中的值,将结果放入寄存器R3中

4.寄存器偏移寻址:

       先将寄存器的值进行移位,再将移位后的数据当做操作数!

        示例:MOV R0,R2,LSL #2    ;将 R2的值逻辑左移两位然后赋值给R0

5.寄存器基址变址寻址

       在寄存器所指定的地址上进行偏移后,再在偏移后的地址上取出值作为操作数

       示例:LDR R0,[R1,#4]   ; 取R1寄存器存储地址向后偏移4个字,从该地址取出值作为操作数读取到R0寄存器中

                  LDR R0, [R1,#4]!     ;功能同上,不过会将偏移后的结果写回这个R1寄存器!即R1寄存器的值会被改变

6.批量寄存器寻址

    示例:LDMIA R0!,{R1,R2,R3,R4}   ; LDM 是数据加载指令 指令后缀IA 表示每一次执行完后R0寄存器中的值增加一个字, 
                                                                后面有感叹号表示将增加后的值写入R0 !

7.相对寻址

    相对寻址是以程序计数器PC 的当前值作为基地址 指令中 的地址标号作为偏移量 将两者相加之后得到操作数作为有效地址!

    示例:BL NEXT
                    ··············
                    NEXT 
                       ···········
            BL NEXT 就是执行NEXT标号后的语句,在这里BL 就用的是相对寻址! NEXT就是偏移量!

8.堆栈寻址

         堆栈寻址是ARM处理器特有一种寻址方式,堆栈寻址使用特定的指令来完成

         示例:STMFD SP1,{R1-R7,LR}    ; 将 R1 - R7 LR 中的值入栈 多用于现场保护(LR为链接寄存器)

                    LDMFD SP1,{R1-R7,LR}    ; 将 数据出栈 分别出到 R1-R7 LR 即现场恢复!

9.块拷贝寻址

        可实现连续的地址数据从存储器的某个位置拷贝到另一个位置

        示例:LDMIA R0!,{R1-R3}    ; 从R0寄存器所存储的地址开始读取三个字到 R1 - R3 
                   STMIA R0!,{R1-R3}    ; 把 R1 - R3 的值存储到R0这个地址上 ,每存储一个字 R0 偏移 1个字