ARM指令集的分类
跳转指令
数据处理指令
程序状态寄存器(PSR)传输指令
Load/Store指令
协处理器指令
异常中断产生指令
ARM指令的语法格式
其中:
Opcode:指令助记符;
[cond]:可选的指令执行条件;
[S]:决定指令的操作是否影响CPSR的值;
ARM指令的编码格式
ARM指令字长固定为32位,一条典型的ARM指令的编码格式如下:
31 28 |
27 25 |
24 21 |
20 |
19 16 |
15 12 |
11 8 |
7 0 |
cond |
001 |
opcode |
S |
Rn |
Rd |
shifter_operand |
ARM指令的条件码域
大多数ARM指令都可以根据CPSR中的标志位的值来决定是否执行该指令。ARMV5以前所有指令都是条件执行的,从ARMV5以后引入了一些必须无条件执行的指令。
每一条ARM指令可以包含四位的条件码,条件码共有16个,各条件吗的助记符及含义如下:
条件码(cond)
|
条件码助记符
|
含义
|
CPSR中条件标志位的值
|
0b0000 |
EQ |
相等(Equal) |
Z==1(Z set) |
0b0001 |
NQ |
Not equal |
Z==0(Z clear) |
0b0010 |
CS/HS |
Carry Set/unsigned higher or same 无符号数大于/等于 |
C==1(C set) |
0b0011 |
CC/LO |
Carry clear/unsigned lower 无符号数小于 |
C==0(C clear) |
0b0100 |
MI |
Minus/negative(负数) |
N==1 |
0b0101 |
PL |
Plus/positive or zero(非负数) |
N==0 |
0b0110 |
VS |
Overflow(上溢出) |
V==1 |
0b0111 |
VC |
No overflow(没有上溢出) |
V==0 |
0b1000 |
HI |
Unsigned higer(无符号数大于) |
C==1 and Z==0 |
0b1001 |
LS |
Unsigned lower or same |
C==0 and Z==1 |
0b1010 |
GE |
Signed greater than or equal |
N==V (N==1 and V==1 or N==0 and V==0) |
0b1011 |
LT |
Signed less than |
N!=V |
0b1100 |
GT |
Signed greater than |
Z clear, and either N set and V set ,or N clear and V clear(Z==0,N==V) |
0b1101 |
LE |
Signed less than or equal |
Z==1 or N!=V |
0b1110 |
AL |
Always(unconditional)无条件执行 |
----------------------- |
0b1111 |
AV |
该指令从不执行 |
----------------------- |
ARM指令寻址方式
1. 数据处理指令的操作数的寻址方式
2. 字及无符号字节的Load/Store指令的寻址方式
3. 杂类Load/Store指令的寻址方式
4. 批量Load/Store指令的寻址方式
5. 协处理器Load/Store指令的寻址方式
数据处理指令中的的操作数的寻址方式
Shifer_operand有三种表示方式:立即数方式,寄存器方式,寄存器移位方式。
立即数方式,每个立即数由一个8位的常数循环右移偶数位得到。其中循环右移的位数由一个4位二进制数的2倍表示。如立即数记作
Immediate = immed_8 循环右移 (2 * rotate_imm)
这样并不是每一个32位常数都是合法的立即数,只有通过以上方法构造的才是合法的立即数。
一个合法的立即数可以有多种编码方法(取不同的immediate和immed_8值),由于循环右移会影响CPSR的C标志位值,因此同一个合法的立即数采用不同的编码方式将使不某些指令产生不同的执行结果,这是不允许的,因此ARM处理器对立即数采用了如下的编码方式:
当立即数值在0和0xFF之间时,令immed_8=
其它情况下编译器使用rotate_imm最小的编码方式。
一.跳转指令
ARM中有两种方式可以实现程序的跳转,一种是跳转指令,另一种是直接向PC(R15)中写入目标地址。后一种方式可以实现在4GB的地址空间中任意跳转,前一种方式可以实现在当前指令前后32M的地址空间中任意跳转。
四种跳转指令:
1. B:跳转指令;
2. BL:带返回的跳转指令(跳转前将PC值保存在LR(R14)中用于返回);
3. BLX:带返回和状态切换的跳转指令;
4. BX:带状态切换的跳转指令。
B和BL(用于子程序调用):
指令语法格式B[L][cond]
指令编码格式
31 |
28 |
27 |
26 |
25 |
24 |
23 0 |
cond |
1 |
0 |
1 |
L |
signed_immed_24 |
L决定是否保存返回值地址,有时保存PC值于LR(R14)中,无时不保存。
target address:指令跳转的目标地址。其计算方法是将指令中的24位带符号数的补码立即数扩展为32位(扩展符号位),将此32位数左移2位,将得到的值加到PC寄存器中得到的即为跳转的目标地址(由此可知跳转范围为-32M-+32M(223*2*2))。
指令操作的伪代码:
If ConditionPassed(cond) then
If L==1 then
LR=address of the instruction after the branch instruction
PC=PC+(SignExtend(Sign_immed_24) << 2)
…..
BLX
BX
二.数据处理指令
数据传送指令用于向寄存器中传入一个常数;
算数逻辑运算指令;
比较指令不保存运算结果,只更新CPSR中相应的条件标志位。
数据处理指令包括:
MOV 数据传送指令
MVN 数据求反传送指令
CMP 比较指令
CMN 基于相反数的比较指令
TST 位测试指令
TEQ 相等测试指令
ADD 加法指令
SUB 减法指令
RSB 逆向减法指令
ADC 带位加法指令
SBC 带位减法指令
RSC 带位逆向减法指令
AND 逻辑与
BIC 位清除
EOR 逻辑异或操作指令
ORR 逻辑或操作指令
1. MOV(P75)
Syntax format:MOV[cond][S] Rd,
Coding format:
31 28 |
27 25 |
24 21 |
20 |
19 16 |
15 12 |
11 8 |
7 0 |
cond |
001 |
1101 |
S |
SBZ(0) |
Rd |
shifter_operand |
The MOV(MOVE) instruction moves the value of
Operation:
If ConditionPassed(cond) then
Rd = shifter_operand
If S == 1 and Rd == R15 then
CPSR = SPSR
If S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = shifter_carry_out
V Flag = unaffected
Usage
MOV is used to:
.Move a value from one register to another.
.Put a constant value into a register.
.Perform a shift without other arithmetic or logical operation.A left shift by n can be used to multiply by 2n.
.When the PC is the destination of the instruction,a branch occurs.The instruction
MOV PC LR can therefore be used to return from a subroutine.
.When the PC is the destination of the instruction and the S bit is set,a branch occurs and the SPSR of the current mode is copied to the CPSR.This means that a MOV PC LR instruction can be used to return from some types of exception.
2. MVN(76)
Syntax format and coding format are same as MOV.
The MVN instruction moves the logical one’s complement(补码) of the value of
Usage
MVN is used to:
.write a negative value into a register
.form a bit mask(位掩码)
.take the one’s complement of a value
3. ADD(76)
Syntax format:ADD[cond][S]
Coding format:
31 28 |
27 25 |
24 21 |
20 |
19 16 |
15 12 |
11 8 |
7 0 |
cond |
001 |
0100 |
S |
Rn |
Rd |
shifter_operand |
The add instruction adds the value of
Operation
if ConditionPassed(cond) then
Rd = Rd + shifter_operand
if S == 1 and Rd == R15 then
CPSR = SPSR
else if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = CarryFrom(Rn + shifter_operand)
V Flag = OverflowFrom(Rn + shifter_operand)
4. ADC(77)
Syntax format and coding format are same as ADD.
The ADC(Add with Carry) instructions adds the value of
Operation
if ConditionPassed(cond) then
Rn = Rn + shifter_operand + C Flag
if S == 1 and Rd == 15 then
CPSR = SPSR
else if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = CarryFrom(Rn + shifter_operand + C Flag)
V Flag = OverflowFrom(Rn + shifter_operand + C Flag)
5. SUB(78)
Syntax format and coding format are same as ADD.
The SUB(Subtract) instruction subtracts the value of
Operation
if ConditionPassed(cond) then
Rd = Rn - shifter_operand
if S == 1 and Rd ==R15 then
CPSR = SPSR
else if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(Rn – shifter_operand)
V Flag = OverflowFrom(Rn – shifter_operand)
6.SBC
The syntax format and coding format are same as sub instruction.
The SBC instruction(Subtract with Carry) instruction is used to synthesize multi-word subtraction. SBC subtracts the value of
Operation
if ConditionPassed(cond) then
Rd = Rn – shifter_operand – NOT(C Flag)
if S==1 and Rd == R15 then
CPSR = SPSR
else if S==1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(Rn – shifter_operand – NOT(C Flag))
V Flag = OverflowFrom(Rn – shifter_Operand – NOT(C Flag))
Usage
SBC is used to synthesize multi-word word subtraction.If register pairs R0,R1 and R2,R3 hold 64 bit values(R0 and R2 hold the least significant words(低字) ),the following instructions leave the 64-bit difference in R4,R5(R4 hold the least significant word):
SUBS R4,R0,R2
SBC R5,R1,R3
7.RSB
The syntax format and coding format are same as the SUB instruction.
The RSB(Reverse Subtract) instruction subtracts the value of register
Operation
if ConditionPassed(cond) then
Rd = shifter_operand – Rn
if S==1 and Rd == R15 then
CPSR = SPSR
else if S==1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(shifter_operand - Rn)
V Flag = OverflowFrom(shifter_operand – Rn)
8.RSC
The syntax format and coding format are same as the SUB instruction.
The Rsc(Reverse Subtract with Carry) instruction subtracts the value of register
Operation
if ConditionPassed(cond) then
Rd = shifter_operand – Rn – NOT(Carry Flag)
if S == 1 and Rd == R15 then
CPSR = SPSR
else if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = NOT BorrowFrom(shifter_operand – Rn – NOT(C Flag))
V Flag = OverflowFrom(shifter_operand – Rn – NOT(C Flag))
Usage
To negate(求负) the 64-bit value in R0,R1,use the following sequence(R0 holds the least significant word) which stores result in R2,R3(R2 holds the least significant word):
RSBS R2,R0,#0
RSC R3,R1,#0
9.AND
Syntax format: AND[cond][S]
The coding format is same as the sub instruction.
The AND instruction performs a bitwise AND of the value of register
Operation
if ConditionPassed(cond) then
Rd = Rd AND(bitwise) shifter_operand
else if S == 1 and Rd == R15 then
CPSR = SPSR
else if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = shifter_carry_out
V Flag = unaffected
Usage
AND is most useful for extracting a field from a register,by ANDing the register with a mask value that has 1s in the field to be extracted,and 0s elsewhere.
10.ORR
The syntax format and coding format are same as the AND instruction.
The ORR(Logical OR) instruction performs a bitwise(inclusive) OR of the value of the register
Operation
if ConditionPassed(cond) then
Rd = Rn OR(bitwise) shifter_operand
if S == 1 and Rd == R15 then
CPSR = SPSR
else if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag = shifter_carry_out
V Flag = unaffected
Usage
ORR can be used to set selected bits in a register.For each bit,OR with 1 sets the bit ,and OR with 0 leaves it unchanged.
三.乘法指令
ARM有两类乘法指令,一类为32位乘法指令(结果为32位),一类为64位乘法指令(结果为64位)。共有6条指令。
1.MUL(Multiply)
Syntax format: MUL[cond][S]
where:
[cond] Is the condition under which the instruction is executed. The conditions are defined in The condition fields in CPRS. If
[S] Causes the S bit(bit[20]) in the instruction to be set to 1 and specifies that the instruction updates the CPSR by setting the N and Z flags according to the result of the multiplication. If S is omitted, the S bit of the instruction is set to 0 and the entire CPSR is unaffected by the instruction.
Conding format:
31 |
28 |
27 |
21 |
20 |
19 |
16 |
15 |
12 |
11 |
8 |
7 |
4 |
3 |
1 |
cond |
0000000 (opcode) |
S |
Rd |
SBZ (0000) |
Rs |
1001 |
Rm |
The MUL(Multiply) instruction is used to multiply signed or unsigned variables to produce a 32-bit result. The condition code are optionally updated, based on the result.
Operation
if ConditionPassed(cond) then
Rd = (Rm * Rs)[31:0]
if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag and V Flag = unaffected
Notes
Because the MUL instruction produces only the lower 32 bits of the 64 bits product, MUL gives the same answer for multiplication of both signed and unsigned numbers.
2.MLA(Multiply Accumulate)
Syntax format: MLA[cond][S]
where
[cond],[S]
Coding format
31 |
28 |
27 |
21 |
20 |
19 |
16 |
15 |
12 |
11 |
8 |
7 |
4 |
3 |
1 |
cond |
0000001 (opcode) |
S |
Rd |
Rn |
Rs |
1001 |
Rm |
The MLA(Multiply Accumulate) multiplies signed or unsigned operands to produce a 32-bit result, which is then added to a third operand, and written to the destination register. The condition code flags are optionally updated, based on the result and the S bit.
Operation
if ConditionPassed(cond) then
Rd = (Rm * Rs + Rn)[31:0]
if S == 1 then
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Flag and V Flag = unaffected
Notes
Because the MLA instructions produces only the lower 32 bits of the 64-bit product, MLA gives the same answer for multiplication of both signed and unsigned numbers.
3.SMULL(Signed Multiplied Long)
Syntax format:SMULL[cond][S]
Coding format:
31 |
28 |
27 |
21 |
20 |
19 |
16 |
15 |
12 |
11 |
8 |
7 |
4 |
3 |
1 |
cond |
0000110 (opcode) |
S |
RdHi |
RdLo |
Rs |
1001 |
Rm |
The SMULL(Signed Multiply Long) instruction multiplies the signed value of the register
Operation
if ConditionPassed(cond) then
RdHi = (Rm * Rs)[63:32]
RdLo = (Rm * Rs)[31:0]
if S == 1 then
N Flag = RdHi[31]
Z Flag = if (RdHi == 0) and (RdLo == 0) then 1 else 0
C Flag and V Flag = unaffected
4.SMLAL(Signed Multiply Accumulate Long)
The Syntax format and coding format are similar as SMULL.
The SMLAL(Signed Multiply Accumulate Long) instruction multiplies the signed value of register
Operation
if ConditionPassed(cond) then
RdLo = (Rm * Rs)[31:0] + RdLo
RdHi = (Rm * Rs)[63:32] + RdHi + CarryFrom((Rm * Rs)[31:0] + RdLo)
if S == 1 then
N Flag = RdHi[31]
Z Flag = if (RdHi == 0) and (RdLo == 0) then 1 else 0
C Flag and V Flag = unaffected
5.UMULL(Unsigned Multiply Long)
The syntax format and coding format are similar as SMULL.
The UMULL(unsigned Multiply Long) instruction multiplies the unsigned value of register
Operation is same as SMULL.
6.UMLAL(Unsigned Multiply Accumulate Long)
The syntax format and coding format are similar as SMLAL.
The UMLAL(Unsigned Multiply Accumulate Long) instruction multiplies the unsigned value of register
Operation is same as SMLAL.