ARM(寻址方式)

1、寻址方式

(1)指令格式
<指令助记符>{<执行条件>} {S}   <目标寄存器>,<操作数1的寄存器> {,<第2操作数>)

注意:

<>号内的项是必需的;(MOV、LDR等)

{ }号内的项是可选的;

S:是否影响CPSR寄存器的值,书写时影响CPSR

CMP不需要增加“s“就可改变相应的标志位
例如:SUBS PC,LR,#4
           MOV  R0,#0X00
           LDR   R0,[R1]
所有指令都是32bit(ARM指令),load/store体系结构(对存储器的访问只能使用加载和存储指令实现)
(2) 条件码与机器码
使用指令条件码可实现高效的逐辑操作,提高代码执行效率。
例如:if(a>b)a++;    CMP       R0,R1

          else b++;            ADDHI    R0,R0,#1
                                        ADDLS    R1,R1,#1(LS:小于等于)

注意:CPSR里面的标志位(不用记)对应于条件码助记符(记)

常用的条件码:EQ NE HI LS 
机器码:MOV  R0,#0×00 <1110 0011 1010 0000000>  0xE3 A0 0000

2、寻址方式(针对源操作效面言)
(1)立即数寻址
MOV RO,10x300
LDX RO,-0X12345678 (伪指令)

注意;8位存效搭,用X表示(0-255),4位存移位的次数,用y表示(0~15),立即数-X循环右移2*Y个位

立即数0XF200是由0XCF2间按表示的,即是由8位的0XF2循环右移24(2*12)得到X=0XF2:Y=0xC
(2)寄存器寻址
MOV R0,R1

(3)寄存器位移寻址
MOV R0,R2,LSL   #3(R2左移三位的值赋给R0,LSL是逻辑左移)

(4)寄存器间接寻址  -LDR/STR(load/stroe)

LDR   R0,R1
STR   R0,R1

LDR和STR指令的数据流的方向相反

(5)基址变址寻址
STR R0,[R1,#-4]
STR R0,[R1,#-4]!(!表示回写)
STR R0,[R1],#-4

(6)多寄存器寻址(Load multiple registers)
STMIA R0!,{R2-R7,R12} 

大括号中的内容表示寄存器中的值,R0对应的是存储器上的地址
注意组合:I/D(Increase/Decrease)A/B(After/Before)
(7)堆栈寻址
STMFD SP!,{R1-R3};压栈,寄存器号大的先入栈

LDMED SP!,{R1-R3};出栈  
注意组合:F/E   I/D

满堆栈:堆栈指针指向最后压入的有效数据项
空堆栈:堆栈指针指向下一个待压入数据的空位置

(8)相对寻址Branch(jmp/cal1)
BBL BLX BX
B跳转指令
BL带返回的跳转指令
BLX带返回和状态切换的跳转指令
BX带状态切换的跳转指令

3、实验

 

 1、     立即数寻址

 R0直接去相应的地址取值

2、     寄存器寻址

 

先将地址赋给R1,再将R1的地址赋给

3、     寄存器间接寻址:

(1)            给相应的地址赋值:

 

 (2)执行前两条命令:

 (3)        执行后两条指令,可以看到相应的地址的值发生改变:

 4、寄存器移位寻址

 先进行移位操作,再将相应的值赋给R0

5、     基址变址寻址

执行前两条命令后寄存器R0R1都已经赋值:

 

 执行第三条指令,将R0寄存器的值赋给R1偏移后的地址

6、基址变址寻址(回显)

 将对R1处理后的值重新赋给R1

7、     基址变址寻址(后变址)

 8、多寄存器寻址

 将四个寄存器上的值放到R0寄存器存储的地址空间上去

 DTMIB,相当于相当于未使用基址

9、堆栈寻址

用栈保护数据:

 先进行压栈操作,将寄存器中的数据存放到存储器上

 对寄存器重新赋值:

 此时,寄存器上的值虽然已经改变,但是存储器上的数据还是原来的数据

 执行出栈操作后,将存储器上的数据重写写入到寄存器,此时的数据还是寄存器的原始数据

10、相对寻址

 在执行跳转指令后并未执行对寄存器R1和R2的操作,直接执行的是对寄存器R3的操作

子程序调用:

 

 

 

 

 
原文地址:https://www.cnblogs.com/zhai1997/p/12684007.html