ARM指令集介绍
3.1 ARM指令集
分为6类:
跳转指令
数据处理指令
程序状态寄存器(PSR)传输指令
Load/Store指令
协处理器指令
异常中断产生指令
3.1.1 跳转指令
ARM实现跳转的两种方式:
跳转指令
直接向PC寄存器(R15)中写入目标地址值
直接向PC写入目标地址值可以实现4GB地址空间任意跳转,称为长跳转。如果在长跳转指令之前使用MOV LR、PC等指令,可以保存将来返回的地址值,就实现了在4GB的地址空间的子程序调用。
ARM版本5及以上体系,实现了ARM指令集和Thumb指令集的混合使用。指令使用目标地址的bit[0]来确定目标程序的类型。bit[0]为1时,目标程序为Thumb指令;bit[0]值为0时,目标程序为ARM指令。
ARM的跳转指令可以从当前指令向前或向后的32MB的地址空间跳转。这类跳转指令有下面4种:
B 跳转指令
BL 带返回的跳转指令
BLX 带返回和状态切换的跳转指令
BX 带状态切换的跳转指令
1.B (跳转指令)及BL(带返回的跳转指令)
这两个指令和目标地址处的指令都属于ARM指令集。二者都可以根据CPSR中条件标志位与指令中的执行条件决定是否执行跳转操作。二者的不同在于B仅仅执行跳转操作,BL指令同时将PC寄存器的值保存到LR寄存器中。
指令的语法格式
B {L} {
target_address的计算方法是:将指令中的24位带符号的补码立即数扩展位32位(扩展其符号位);将此32位数左移两位;将得到的值加到PC寄存器,即得到跳转的目标地址。跳转的范围大致为-32MB~+32MB
ARM汇编器通过下面步骤计算signed_immed_24:
将PC寄存器的值作为本跳转指令的基地址值
从跳转的目标地址中减去上面所说的跳转的基地址值,生成字节偏移量。由于ARM指令是字对齐的,该字节偏移量为4的倍数
当上面生成的自己偏移量超过范围33554432~33554430时,程序需要相应的处理
否则,将指令编码字中的signed_immed_24设置成上述字节偏移量的bits[25:0]
2.BLX(1)
语法格式:
BLX
第1种格式的BLX指令,从ARM指令跳转到指令中指定的目标地址,并将程序切换为Thumb状态,该指令同时将PC寄存器的内容复制到LR寄存器中。
当子程序为Thumb指令集,而调用者是ARM指令集时,可以通过BLX指令实现子程序调用和程序状态的切换。
3.BLX(2)
语法格式:
BLX {
第2种格式从ARM指令集跳转到指定的目标地址,目标地址的指令可以是ARM指令,也可以是Thumb指令。目标地址放在指令中的寄存器
4.BX指令
跳转到指定的目标地址,目标地址处的指令可以是ARM指令,也可以是Thumb指令。目标地址值为指令的值和0xFFFFFFFE做与结果,目标地址处的指令类型由寄存器
语法格式:
BX {
3.1.2 数据处理指令
3类:
数据传送指令,如MOV
算术逻辑运算指令,如ADD、SUB、AND
比较指令,如TST
数据处理指令包括:
MOV 数据传送指令
MVN 数据求反传送指令
CMP 比较指令
CMN 基于相反数的比较指令
TST 位测试指令
TEQ 相等测试指令
ADD 加法指令
SUB 减法指令
RSB 逆向减法指令
ADC 带位加法指令
SBC 带位减法指令
RSC 带位逆向减法指令
AND 逻辑与操作指令
BIC 位清除指令
EOR 逻辑异或操作指令
ORR 逻辑或操作指令
3.1.3 乘法指令
两类:
32位的乘法指令,即乘法的结果为32位
64位的乘法指令,即乘法的结果为64位
以下6条:
MUL 32位乘法指令
MLA 32位带加数的乘法指令
SMULL 64位有符号数乘法指令
SMLAL 64位带加数的有符号数乘法指令
UMULL 64位无符号数乘法指令
UMLAL 64位带加数的无符号数乘法指令
3.1.4 杂类的算术指令
CLZ指令,用于计算操作数最高端0的个数。
计算操作数规范化时需要左移的位数
确定一个优先级掩码中最高优先级
CLZ {
} ,
3.1.5 状态寄存器访问指令
状态寄存器需注意:
状态寄存器有些位是没有使用的
程序不能通过改变CPSR中的T控制位直接将程序状态切换到thumb状态,必须通过BX等指令完成状态的切换
修改状态寄存器是通过“读取-修改-写回”的操作序列实现的
状态寄存器访问指令包括以下两条:
MRS 状态寄存器到通用寄存器的传送指令
MSR 通用寄存器到状态寄存器的传送指令
MRS {
通过“读取-修改-写回”操作序列修改状态寄存器的内容。
当异常中断允许嵌套时,需要在进入异常中断之后,嵌套中断发生之前保存当前处理器模式对应的SPSR。这时需要通过MRS指令读出SPSR的值,再用其他指令将SPSR的值保存起来
在进程切换时也需要保存当前状态寄存器值
MRS {
通常用于恢复状态寄存器的内容或者改变状态寄存器的内容
当退出异常中断处理程序时,如果事先保存了状态寄存器的内容,通常通过MSR指令将事先保存的状态寄存器内容回复到状态寄存器中
当需要修改状态寄存器的内容时,通过“读出-修改-写回”指令序列完成。
3.1.6 Load/Store内存访问指令
Load指令用于从内存中读取数据放入寄存器中
Store指令用于将寄存器中的数据保存到内存
两大类:
32位的字类型数据以及8位无符号的字节型数据
16位半字类型数据以及8位有符号数字节类型数据
第一类:
LDR 字数据读取指令
LDRB 字节数据读取指令
LDRBT 用户模式的字节数据读取指令
LDRH 半字数据读取指令
LDRSB 有符号的字节数据读取指令
LDRSH 有符号的半字数据读取指令
LDRT 用户模式的字数据读取指令
STR 字数据写入指令
STRB 字节数据写入指令
STRBT 用户模式字节数据写入指令
STRH 半字数据写入指令
STRT 用户模式字数据写入指令
3.1.7 批量Load/Store内存访问指令
主要有以下几条:
LDM(1) 批量内存字数据读取指令
LDM(2) 用户模式的批量内存字数据读取指令
LDM(3) 带状态寄存器的批量内存字数据读取指令
STM(1) 批量内存字数据写入指令
STM(2) 用户模式的批量内存字数据写入指令
3.1.8 信号量操作指令
信号量用于进程间的同步和互斥。
两条指令完成信号量的操作:
SWP 交换指令
SWPB 字节交换指令
3.1.9 异常中断产生指令
SWI 软中断指令
BKPT 断点中断指令
3.1.10 ARM协处理器指令
3类:
用于ARM处理器初始化ARM协处理器的数据处理操作
用于ARM处理器的寄存器和ARM协处理器的寄存器间的数据传送操作
用于在ARM协处理器的寄存器和内存单元之间传送数据
5条指令:
CDP 协处理器数据操作指令
LDC 协处理器数据读取指令
STC 协处理器数据写入指令
MCR ARM寄存器到协处理器寄存器的数据传输指令
MRC 协处理器寄存器到ARM寄存器的数据传送指令
3.2 一些基本的ARM指令功能段
3.2.1 算术逻辑运算指令的应用
位操作指令应用
实现乘法的指令段举例
64位数据运算举例
转换内存中数据存储方式的指令段
3.2.2 跳转指令的应用
子程序调用
BL指令在执行跳转操作的同时保存当前PC寄存器值,用于从被调用的子程序中返回。
...
BL function
...
...
function
...
...
MOV PC, LR条件执行
条件判断语句
循环语句
多路分支程序语句
3.2.3 Load/Store指令的应用
链表操作
简单串比较
长跳转
多路跳转
3.2.4 批量Load/Store指令的应用
简单的块复制
子程序进入和退出时数据的保存和恢复
3.2.5 信号量指令的应用
信号量用于实现对临界区数据访问的同步。当信号量为0时,表示与该信号量相关的临界区可用;当信号量的值为-1时,表示当前进程正在查看该信号量的值。
3.2.6 与系统相关的一些指令代码段
SWI中断处理程序示例
SWI指令使处理器切换到特权模式,在特权模式下请求特定的系统服务。
IRQ中断处理程序示例
在ARM中,外部管理器或外设通过使能ARM处理器中的IRQ输入管脚产生IRQ异常中断。
CPSR寄存器中的I控制位为1禁止响应中断请求,为0在指令边界处检查是否有IRQ中断请求。
进程切换
进程是操作系统中任务调度的基本单位。每个进程由一个进程控制块PCB来表示,进程控制块PCB包含了进程相关信息。
3.3 Thumb指令介绍
Thumb指令集指令长度为16位。
Thumb指令集并没有改变ARM体系底层的程序设计模型,只是在该模型上增加了一些限制条件。Thumb指令集中的数据处理指令的操作数仍然是32位,指令寻址地址也是32位的
处理器执行Thumb指令时,可以使用的整数寄存器通常为R0~R7,有些指令可以使用PC、R14(LR)以及栈指针寄存器SP(R13)。
在Thumb状态下,读取R15寄存器时,位[0]位0,位[31:1]包含了程序计数器的值;在向R15写入数据时,位[0]被忽略,位[31:1]被设置为当前程序计数器的值。
Thumb指令集没有提供访问CPSR/SPSR寄存器的指令。处理器根据CPSR寄存器中的T位来确定指令类型。T为0,指令为ARM指令;T为1,指令为Thumb指令