ARM体系结构与编程-第三章
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} {<cond>} <target_address>
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 <target_address>
第1种格式的BLX指令,从ARM指令跳转到指令中指定的目标地址,并将程序切换为Thumb状态,该指令同时将PC寄存器的内容复制到LR寄存器中。
当子程序为Thumb指令集,而调用者是ARM指令集时,可以通过BLX指令实现子程序调用和程序状态的切换。
3.BLX(2)
语法格式:
BLX {<cond>} <Rm>
第2种格式从ARM指令集跳转到指定的目标地址,目标地址的指令可以是ARM指令,也可以是Thumb指令。目标地址放在指令中的寄存器<Rm>中,该地址的bit[0]值为0,目标地址处的指令类型由CPSR中的T位决定。该指令同时将PC寄存器的内容复制到LR寄存器中。
4.BX指令
跳转到指定的目标地址,目标地址处的指令可以是ARM指令,也可以是Thumb指令。目标地址值为指令的值和0xFFFFFFFE做与结果,目标地址处的指令类型由寄存器<Rm>的bit[0]决定。
语法格式:
BX {<cond>} <Rm>
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 { <cond> } <Rd> , <Rm>
-
3.1.5 状态寄存器访问指令
状态寄存器需注意:
-
状态寄存器有些位是没有使用的
-
程序不能通过改变CPSR中的T控制位直接将程序状态切换到thumb状态,必须通过BX等指令完成状态的切换
-
修改状态寄存器是通过“读取-修改-写回”的操作序列实现的
状态寄存器访问指令包括以下两条:
-
MRS 状态寄存器到通用寄存器的传送指令
-
MSR 通用寄存器到状态寄存器的传送指令
MRS {<cond>} <Rd>, CPSR
-
通过“读取-修改-写回”操作序列修改状态寄存器的内容。
-
当异常中断允许嵌套时,需要在进入异常中断之后,嵌套中断发生之前保存当前处理器模式对应的SPSR。这时需要通过MRS指令读出SPSR的值,再用其他指令将SPSR的值保存起来
-
在进程切换时也需要保存当前状态寄存器值
MRS {<cond>} <Rd>, SPSR
-
通常用于恢复状态寄存器的内容或者改变状态寄存器的内容
-
当退出异常中断处理程序时,如果事先保存了状态寄存器的内容,通常通过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指令