ARM处理器的寻址方式
寻址方式是根据指令给出的地址码字段来实现寻找真实操作地址的方式。arm处理器共有8种寻址方式 。
1.寄存器寻址
寄存器寻址指令中的代码码字段指的是寄存器编号,操作数的值在寄存器中,指令执行时可直接取出寄存器中的值来操作
示例:
MOV R1,R2 ; 将R2的值存到R1中。
SUB R0,R1,R2 ; 将R1的值减R2的值,结果保存在R0。
2.立即寻址
操作码字段后面的地址码就是操作数,取出指令同时也取出了操作数。
示例:
SUBS R0,R0,#1 ; R0减1,结果放入R0,并且影响标志位。
MOV R0,#0xFF000 ; 将立即数0xFF000装入R0寄存器。
3.寄存器移位寻址
ARM指令集特有的寻址方式。当第二个操作数是寄存器移位方式时,在与第一个操作数结合之前,选择进行移位操作。
可采用的移位操作如下:
- LSL 逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补0。
- LSR 逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补0。
- ASR 算术右移(Arithemetic Shift Right),移位过程中保持符号位不变,若源操作数为正数,则字的高端空位补0,否则补1。
- ROR 循环右移(ROtate Right),由字的低端移出的位填入高端空出的位。
- RPX 带拓展的循环右移(ROtate Right eXtended by 1 place),操作数右移一位,高端空位用原C标志值填充。
示例:
MOv R0,R2,LSL #3 ;R2的值左移三位,结果放入R0,即 R0=R2x8。
ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,再与R1进行与运算,结果存到R1中。
4.寄存器间接寻址:
指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。
示例:
LDR R1,[R2] ; 将R2指向的存储单元的数据读出,保存在R1中。
SWP R1,R1,[R2] ; 将存储器R1的值和R2指定的存储单元的内容交换。
5.基址寻址
基址寻址就是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址。基址寻址用于访问基址附近的存储单元,常用于查表、数组操作、功能部件寄存器访问等。
示例:
LDR R2,[R3,#0x0C] ; 读取R3+0x0C地址上的存储单元的内容,存入R2。
STR R1,[R0,#-4] ; 先R0=R0-4,然后把R1的值保存到R0指定的存储单元。
LDR R1,[R0,R3,LSL #1] ; 先将R3左移一位,再与R1相加,所得结果存入R1。
6.多寄存器寻址(常用)
多寄存器寻址一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。
示例:
LDMIA R1!,{R2-R7,R12} ; 将R1指向的单元中的数据读到R2-R7,R12中,R1自动加一
STMIA R0!,{R2-R7,R12} ; 将R2-R7,R12中的值保存到R0指向的存储单元,R0自动加一。
7.堆栈寻址:
堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出” 。堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶。
存储器堆栈可分为两种:
-
向上生长:写入数据后,堆栈指针变大,向高地址的方向生长,称为递增堆栈。
-
向下生长:写入数据后,堆栈指针变小,向低地址的方向生长,称为递减堆栈。
!!除了考虑堆栈指针的增长方向以外,还要考虑入栈时是否可以直接向堆栈指针指向的存储单元写入数据。
ARM7支持两种情况:
-
堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;
-
堆栈指针指向下一个待压入数据的空位置,称为空堆栈。
综上所述,可以得到四种堆栈类型:
-
满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA、STMFA等。
-
空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA、STMEA等。
-
满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD、STMFD等。
-
空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如LDMED、STMED等。
示例:
STMFD SP!,{R!-R7,LR} ; R1-R7,LR入栈,满递减
LDMFD SP!,{R!-R7,LR} ; 数据出栈,放入R1-R7,LR寄存器,满递减
8.相对寻址:
相对寻址是基址寻址的一种变通。由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。
示例:
BL SUBR1 ;调用子程序SUBR1
BEQ LOOP ;条件跳转到LOOP标号处
.
.
LOOP MOV R6,#1
.
.
SUBR1 ......
—power by Lzy