第二操作数可以是立即数,也可是是寄存器
如果是立即数就必须要满足除0外的8位在连接首位的圆圈内是宽度不超过8的(紧挨在一起的)同时还要满足宽度不能是奇数,因为循环移动是是移动的偶数,所以当宽度是奇数时就对不齐了表示不了
移位操作只有两位,只能保留4种,ASR、LSL、LSR、ROR
具体指令
ADD、SUB、RSB、ADC、SBC、RSC
加、减、反减,不带进位和带进位
条件码标志,如果带上S则根据结果要更新NZCV
R15的使用:
若将R15作为Rn(第一操作数寄存器)使用则它的值是指令的地址加上对应偏移量(三级流水线加8)相当于读程序计数器的值
若使用R15作为Rd(目的寄存器),相当于要改写,这是不允许的所以有对应特殊的用法
则:
立即跳转
异常返回,只有发生异常时才能使用
禁止修改
AND、ORR、EOR、BIC
逻辑与、或、异或、位清零
条件码标记:
若指定S,则根据结果更新标志N、Z,在计算第二操作数时更新C,不影响标志V
MOV和MVN(传送和取反)
条件码标志:
同上一个影响相同
CMP和CMN(比较和比较反值)
用法:将寄存器的值与第二操作数进行比较。他们根据结果更新条件标志位,但结果不放到任何寄存器中
CMP:根据Rn - Op2设置条件码,结果丢弃
CMN:根据Rn + Op2设置条件码,结果丢弃
条件码:根据结果NZCV都可能改变
TST和TEQ(测试和测试相等)
句法:
TST {cond} Rn, Operand2
TEQ {cond} Rn, Operand2
用法:
TST:对Rn的值和Operand2的值进行按位与操作,设置条件码,丢弃结果
TEQ:对Rn的值和Operand2的值进行按位异或操作,设置条件码,丢弃结果
乘法指令
可以看出Rd, Rn都可以作为目的寄存器,但是Rn也作需要加时存放的,为了能表示32位和64位,当表示32位是只使用Rd,但是要表示64位是就需要同时使用Rd和Rn了,此时Rd作为高位,Rn作为低位。
MUL和MLA(乘法和乘加)
句法:
MUL {cond} {S} Rd, Rm, Rs
MLA {cond} {S} Rd, Rm, Rs, Rn
R15不能用作Rd、Rm、Rs、Rn。
Rn不能与Rm相同
条件标志码:根据结果更新N和Z,不影响V,C不用看
UMULL、UMLAL、SMULL、SMLAL
无符号和带符号长乘数乘法和乘加,结果为64位
句法:
Op {cond} {S} RdLo, RdHi, Rm, Rs
也可以使用半字进行运算
保持原来的32位<x,y>中填W
ARM的数据存储指令Load/Store是唯一用于寄存器和存储器之间进行数据传送的指令。
分类:
单寄存器的存取指令(LDR, STR)
多寄存器存取指令(LDM, STM)
单寄存器交换指令(SWP)
单寄存器的存取指令
根据传送数据类型的不同可以分为:
单字和无符号字节的数据传送指令
汇编格式:
LDR|STR {<cond>} {B} Rd, [Rn, <offset>]{!}
LDR|STR {<cond>} {B} {T} Rd, [Rn], <offset>
LDR|STR {cond} {B} Rd, LABEL
T:是特权模式下使用,在用户模式下不可用。
半字和有符号字节的数据传送指令
汇编格式:
前变址格式
LDR|STR{<cond>} H|SH|SB Rd, [Rn, <offest>] {!}
后变址格式
LDR|STR {<cond>} H|SH|SB Rd, [Rn], <offest>
可以是8位立即数或 寄存器
其中
SH:带符号的半字
H:无符号的半字
SB:带符号的字节
半字传送的地址必须是偶数
LDR和STR双字
加载两个相邻的寄存器和存储两个相邻的寄存器,64位双字
句法:
op {cond} D Rd, [Rn]
op {cond} D Rd, [Rn, offset] {!}
op {cond} D Rd, label
op {cond} D Rd, [Rn], offset
其中:Rd 加载或存储寄存器其中一个,另一个是R(d + 1)。Rd必须是偶数寄存器,且不是R14
Rn 除非指令为零偏移,或不带回写的前索引,否则,Rn不允许与Rd和R(d + 1)相等
例:
LDRD R6, [R11]
STRD R4, [R9, #24]
STRD R0, [R9, R2]!
多寄存器存取指令LDM/STM
可以将16个寄存器(R0~R15)的任意集合存储到存储器或从存储器读到寄存器
汇编格式:
LDM/STM {<cond>} <add mode> Rn{!}, <REGISTERS>{^}
单寄存器交换指令(SWP)
汇编格式:
SWP {B} {<cond>} Rd, Rm, [Rn]
例句:
SWPB R1, R1, [R0] 交换字节,将[R0]中的字节数据读取到R1中,同时将R1中的数据写入到[R0]中
SWP R1, R2,[R3] 交换字节数据,将[R3]中的数据读取到R1中,同时将R2中的数据读入到[R3]中
MRS {<cond>} Rd, CPSR|SPSR
MSR {<cond>} CPSR_f | SPSR_f, #<32-bit immediate>
MSR {<cond>} CPSR_<field> | SPSR_<field>, Rm
field表示:ARM的转移指令可以从当前指令向前或向后的32MB的地址空间跳转,根据完成的功能他可以分为:
B {L} {<cond>} <target address>
B {L} X {<cond>} Rm
BLX <target address>
BX格式中:Rm的第0位拷贝到CPSR的T位,[31:1]位移入PC。若Rm[0] = 1, 切换到Thumb状态,Rm最低位清0,从Rm开始执行;若Rm[0] = 0将Rm[1]位清0,从Rm开始执行。异常中断可以分为两种
SWI {<cond>} <24为立即数>
BKPT {immed_16}
软件中断指令SWI用于产生SWI异常中断,用来实现在用户模式下队操作系统中特权模式的程序的调用;断点中断指令BKPT主要用于产生软件中断,龚供调试程序用。
CLZ {<cond>} Rd, Rm
说明:MOV R11, #0x35E20 //LDR伪指令
CLZ R5, R11 // R5 = 14
ARM支持16个协处理器,用于各种协处理器操作
CDP {<cond>} <CP#>, <Cop1>, CRd, CRn, CRm{, <Cop2>}
CP#: 协处理器名,标准名为pn, n为0~15范围内的整数LDC|STC {<cond>} {L} <CP#>, CRd, [Rn <offset>] {!}
LDC|STC{<cond>} {L} <CP#>, CRd, [Rn], <offset>
MRC {<cond>} <CP#>, <Cop1>, Rd, CRn, CRm {, <Cop2>}
MCR {<cond>} <CP#>, <Cop1>, Rd, CRn, CRm {, <Cop2>}
未完待续