ARM 处理器寻址方式
ARM 处理器寻址方式
寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式,ARM处理器有9种基本寻址方式.
1. 寄存器寻址
操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编码,指令执行时直接取出寄存器值操作.
例子:
MOV R1, R2 ;R2 -> R1
SUB R0,R1,R2 ;R0 = R1 - R2
2. 立即寻址
立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令中,取出指令也就取出了立即使用的操作数(立即数).
例子:
SUBS R0,R0,#1 ;R0 = R0 - 1
MOV R0,#0xff00 ;R0 = 0xff00
立即数要以'#'为前缀,表示16进制时用'0x'
3. 寄存器偏移寻址
寄存器偏移寻址是ARM指令集特有的寻址方式,当第2个操作数是寄存器偏移方式时第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作.
例子:
MOV R0,R2,LSL,#3 ;R2的值左移3位,结果放入R0,即R0 = R2*8
ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后与R1相与操作,结果放入R1
可采用的移位操作:
LSL: 逻辑左移, 寄存器中字的低端空出的位补0.
LSR: 逻辑右移,寄存器中字的高端空出的位补0.
ASR: 算术右移,移位过程中保持符号不变,即如果源操作数是正数,则字的高端空出的位补0,否则补1.
ROR: 循环右移,由字的低端移出的位填入字的高端空出的位.
RRX: 带扩展的循环右移,操作数右移一位,高位空出的位用原C标志值填充.
4. 寄存器间接寻址
寄存器间接寻址指令中的地址码给出的是一个通用寄存器编码,所需要的操作数保存寄存器指定地址的存储单元中,即寄存器为操作数的地址指针.
例子:
LDR R1,[R2] ;将R2中的数值作为地址,取出此地址中的数据保存在R1中
SWP R1,R1,[R2] ;将R2中数值作为地址,取出地址中的数值与R1中的值交换.
5. 基址寻址
基址寻址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,机制寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等.
例子:
LDR R2,[R3,#0xOF];将R3中数值加0x0F作为地址,取出此地址的值保存到R2中.
STR R1,[R0,#-2]; 将R0中的数值减2作为地址,把R1中的内容保存到此地址位置
6. 多寄存器寻址
多寄存器寻址就是一次可以传送几个寄存器值. 允许一条指令传送16个寄存器的任何子集或所有寄存器.
例子:
LDMIA R1!,{R2 - R7, R12} ;将R1单元中的数据读出到R2-R7中,R12,R1自动加1
STMIA R0!, {R3-R6, R10} ;将R3-R6,R10中的数据保存到R0指向的地址, R0自动加1
7 堆栈寻址
堆栈是特定顺序进行存取的存储区,操作顺序是先进后出,堆栈寻址时隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域( 堆栈),指针所指向导存储单元就是堆栈的栈顶,存储器堆栈可分为两种:
向上生长: 向高地址方向生长,成为递增堆栈
向下生长: 向地址方向生长,成为递减堆栈
堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个要放入的空位置,成为空堆栈.这样就有4中类型的堆栈表示递增和递减的满堆栈和空堆栈的组合.
满递增: 堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址.指令如LDMFA,STMFA等.
空递增: 堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置.指令如LDMEA, STMEA等.
满递减: 堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址.指令如LDMFD,STMFD等.
空递减: 堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置.指令如LDMED,STMED等.
8. 块拷贝寻址
多个寄存器传送指令用于一块数据从存储器的某个位置拷贝到另一个位置.
例子:
STMIA R0!,{R1-R7} ;将R1~R7的数据保存到存储器中,存储器指针在保存第一个值后增加,增长方向为向上增长.
9. 相对寻址
相对寻址是基址寻址的一种变通,由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到地址即为操作数的有效地址.
例子:
BL ROUTE1 ;调用ROUTE1子程序