文章目录
- 1.ARM处理器寻址方式*
- (1)寄存器寻址--直接操作寄存器
- (2)立即寻址--直接对数字进行操作
- (3)寄存器移位寻址
- (4)寄存器间接寻址--寄存器存储的数据地址,标志:【】
- (5)基址寻址-寄存器+偏移量=真实地址
- (6)多寄存器寻址
- (7)堆栈寻址
- (8)相对寻址--PC提供基址的基址寻址:PC+偏移=真实地址
ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制较为简单。学习该指令可以使得我们更加了解ARM指令。ARM 具有
32 位 ARM 指令集和
16 位 Thumb 指令集,ARM 指令集效率高,但是代码密度低; 而 Thumb 指令集具有较高的代码密度,却仍然保持 ARM 的大多数性能上的优势,它是 ARM 指令集的子集。所有的 ARM 指令都是可以有条件执行的,而 Thumb 指令仅有一条指令具备条件执行功能。ARM 程序和 Thumb 程序可相互调用,相互之间的
状态切换开销几乎为零。
1.ARM处理器寻址方式*
寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式。ARM 处理器具有 9 种基本寻址方式
(1)寄存器寻址–直接操作寄存器
操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值来操作。寄存器寻址指令举例如下:
MOV R1,R2 ; 将 R2 的值存入 R1
SUB R0,R1,R2 ;将 R1 的值减去 R2 的值,结果保存到 R0
(2)立即寻址–直接对数字进行操作
立即寻址指令中的操作码字段后面的地址码部分即是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(这样的数称为立即数)。立即寻址指令举例如下:
(#号标志着立即数,subs表示影响标志位,修改标志位的操作可以看作返回bool类型)
SUBS R0,R0,#1 ;R0 减 1,结果放入 R0,并且影响标志位
MOV R0,#0xFF000 ;将立即数 0xFF000 装入 R0 寄存器
(3)寄存器移位寻址
寄存器移位寻址是 ARM 指令集特有的寻址方式。当第 2 个操作数是寄存器移位方式时,第 2 个寄存器操作数在与第 1 个操作数结合之前,选择进行移位操作。寄存器移位寻址指令举例如下:
(对单操作数指令而言:第一个寄存器是目标寄存器,LST:逻辑左移,R2:第一个寄存器操作数,LST R3:第二个寄存器操作数)
MOV R0,R2,LSL #3 ;R2 的值左移 3 位,结果放入 R0,即是 R0=R2×8
ANDS R1,R1,R2,LSL R3 ;R2 的值左移 R3 位,然后和 R1 相“与”操作,结果放入 R1
(对双操作数指令而言:第一个寄存器是目标寄存器,LST:逻辑左移,R1:第一个寄存器操作数, R2:第二个寄存器操作数,LST R3:第三个寄存器操作数,表示R2要先和R3进行左移操作)
(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 指定的存储单元
(6)多寄存器寻址
多寄存器寻址一次可传送几个寄存器值,允许一条指令传送 16 个寄存器的任何子集或所有寄存器。多寄存器寻址指令举例如下:
LDMIA R1!,{R2-R7,R12} ;将 R1 指向的单元中的数据读出到 R2~R7、R12 中(R1 自动加 4)
STMIA R0!,{R2-R7,R12} ;将寄存器 R2~R7、R12 的值保存到 R0 指向的存储;(R0 自动加 4)
这里需要稍作解释,不是说R2-R6依次覆盖R0的内容,而是R0每次存储了一个寄存器的内容之后,比如先存储R2,就进行+4操作,因为32bit,4字节,然后再存储R3,再+4,依次存储右侧所有寄存器的内容。
(7)堆栈寻址
堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出” 。堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶。存储器堆栈可分为两种:
向上生长:向高地址方向生长,称为递增堆栈,指令如 LDMFA、STMFA 等。
向下生长:向低地址方向生长,称为递减堆栈,指令如 LDMFD、STMFD 等。
堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈
所以可以组合出四种类型的堆栈方式:
满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA、STMFA等;
空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA、STMEA等;
满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD、STMFD等;
空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如LDMED、STMED等。
(8)相对寻址–PC提供基址的基址寻址:PC+偏移=真实地址
相对寻址是基址寻址的一种变通。由程序计数器 PC 提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。相对寻址指令举例如下:
BL SUBR1 ;调用到 SUBR1 子程序
BEQ LOOP ;条件跳转到 LOOP 标号处
…
LOOP MOV R6,#1
…
SUBR1 … ;单元的内容交换