寻址方式是根据指令中给出的地址码字段来实现寻找操作数地址的方式,ARM中有以下8种基本的寻址方式。
将寄存器中的值作为操作数,指令中的地址码字段是寄存器编号。
MOV R1,R2 ;R1 = R2
ADD R0,R1,R2 ;R0 = R1 + R2
将操作数直接写到指令中,取出指令也就取出操作数,直接使用。
MOV R1,#0xFFF0 ;R1 = 0xFFF0
SUBS R1,R1,#0xF0 ;R1 = R1 - 0xF0
寄存器移位寻址是ARM指令集特有的寻址方式。当第2个操作数是寄存器移位方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。
MOV R0,R1,LSR #2 ;R1的值右移2位,结果放入R0
ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1“与”操作,结果放入R1
其中移位操作有
LSR(Logical Shift Right)逻辑右移,高位补0
LSL(Logical Shift Left)逻辑左移,低位补0
ASR(Arithmetic Shift Right)算术右移,符号位不变,高位补符号位数值
ROR(ROtate Right)循环右移,低位补高位
RRX(ROtate Right eXtended by 1 place),操作数右移1位,高位补C标志位
操作数是以寄存器中的值作为地址所对应的值,即寄存器中的值为操作数的地址指针。
LDR R1,[R2] ;R1 = *R2
SWP R1,R1,[R2] ;交换R1和*R2
将基址寄存器的内容加上需要的偏移量,得到需要操作数的有效地址,常用于查表和数组操作。
LDR R1,[R2,#0xFC] ;R1 = *(R2+0xFC)
LDR R1,[R2,#0xFC]! ;R1 = *(R2+0xFC),R2 = R2 + 0xFC
STR R1,[R2,#0xFC]! ;R2 = R2 + 0xFC,*R2 = R1
LDR R0, [R1, R2] ;R0 = *(R1+R2)
一条指令可以完成多个寄存器值得传送,一条指令可以传送16个寄存器的任何自己和所有寄存器。
LDMIA R1!,{R2-R7,R12} ;将R1指向的单元中的数据读到R2-R7,R12中,R1++
STMIA R0!,{R2-R7,R12} ;中将R2-R7,R12中的值保存到R1指向的单元,R0++
堆栈指针移动方向称生长方向,ARM7有:
除SP移动方向有所不同,SP指向的位置也有所不同:
根据SP生长方向和指向位置不同组合,得到4中堆栈类型:
STMFD SP!,{R!-R7,LR} ;R1-R7,LR入栈,满递减
LDMFD SP!,{R!-R7,LR} ;数据出栈,放入R1-R7,LR寄存器,满递减
与基址寻址类似,以程序计数器PC为基准地址,指令中声明偏移量,相加即得到操作数的有效地址。
BL SUBR1 ;调用子程序SUBR1
BEQ LOOP ;条件跳转到LOOP标号处
.....
LOOP MOV R6,#1
......
SUBR1 ......