ARM指令集——数据处理指令篇

输出传送指令包括以下指令:

  • MOV 数据传送指令
  • MVN 数据求反传送指令
  • CMP 比较指令
  • CMV 基于相反数的比较指令
  • TST 位测试指令
  • TEQ 相等测试指令
  • ADD 加法指令
  • SUB 减法指令
  • RSB 逆向减法指令
  • ADC 带位加法指令
  • SBC 带位减法指令
  • RSC 带位逆向减法指令
  • AND 安位与指令
  • BIC 为清零指令
  • EOR 逻辑异或指令
  • ORR 逻辑或指令
下面分别作详细介绍:

1、MOV传送指令
指令的语法格式:
MOV{}{S} ,
指令操作的伪代码:
if ConditionPassed(cond) then
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 = shiter_carry_out
V Flag = unaffected

指令的使用 
MOV指令可以完成以下功能:
  • 将数据从一个寄存器传送到另一个寄存器;
  • 将一个常数传送到到另一个寄存器中;
  • 实现单纯的移位操作;
  • 当PC寄存器作为目标寄存器时可以实现程序跳转。这种跳转可以实现子程序调用以及从子程序中返回;
  • 当PC寄存器作为目标寄存器且指令中S位被设置时,指令在执行跳转操作的同时,将当前处理器模式的SPSR寄存器内容复制到CPSR中,这样指令MOVS PC, LR可以实现从某些异常中断中返回。

2、MVN传送指令
指令的语法格式:
MVN{}{S} ,
指令操作的伪代码:
if ConditionPassed(cond) then
Rd = NOT 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 Falg = shifter_carry_out
V Flag = unaffected

3、ADD加法指令
指令的语法格式:
ADD{}{S} , ,

指令操作的伪代码:
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 Falg = CarryFrom(Rn + shifter_operand)
V Flag = OverflowFrom(Rn + shifter_operand)
指令的使用:
ADD指令实现了两个操作数相加。

4、ADC带位加法指令
指令的语法格式:
ADC{}{S} , ,

指令操作的伪代码:
if ConditionPassed(cond) then
Rd = Rn + shifter_operand + C Flag
if S == 1 and Rd == R15 then
CPSR = SPSR
else if S == 1
N Flag = Rd[31]
Z Flag = if Rd == 0 then 1 else 0
C Falg = CarryFrom(Rn + shifter_operand +C Flag)
V Flag = OverflowFrom(Rn + shifter_operand + C Flag)

指令的使用:
ADC指令和ADD指令联合使用可以实现两个64位的操作数相加。如果寄存器R0和R1中放置一个64位的源操作数,其中R0中放置低32位数值;寄存器R2和R3中存放另一个64位源操作数,其中R2中放置低32位数值,下面的指令序列实现了两个64位操作数的加法操作。
ADDS R4, R0, R2
ADC R5, R1, R3

5、SUB减法指令
指令的语法格式:
SUB{}{S} , ,

操作指令的伪代码:
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 Falg = NOT BorrowFrom(Rn - shifter_operand)
V Flag = OverflowFrom(Rn - shifter_operand)

指令的使用:
需要注意的是,在SBCS指令中,如果发生了借位操作,CPSR寄存器中的C标志位设置成0,如果没有发生借位操作,则设置成1,这与ADDS指令的进位操作刚好相反。

6、SBC带位减法指令
指令的语法格式:
SBC{}{S} , ,
指令操作的伪代码:
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 - NOT(C Flag))
V Flag = OverflowFrom(Rn - shifter_operand - NOT(C Flag))
指令的使用:
SBC指令和SUBS指令联合使用可以实现两个64位操作数相减。如果寄存器R0和R1中放置一个64位的源操作数,其中R0中放置低32位数值;寄存器R2和R3中放置另一个64位的源操作数,其中R2中放置低32位数值。下面的指令序列实现了两个64位操作数的减法操作。
SUBS R4, R0, R2
SBC R5, R1, R3
需要注意的是,在SBCS指令中,如果发生了借位操作,CPSR寄存器中的C标志位设置成0,如果没有发生借位操作,则设置成1,这与ADDS指令的进位操作刚好相反。

7、RSB逆向减法指令
指令的语法格式:
RSB{}{S} , ,
指令操作的伪代码:
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)

指令的使用
RSB Rd, Rx, #0 ; Rd = -Rx
RSB Rd, Rx, Rx, LSL #n ; Rd = Rx * 2^n -Rx
需要注意的是,在SUBS指令中,如果发生了借位操作,CPSR寄存器中的C标志位设置成0;如果没有发生借位操作,CPSR寄存器中的C标志位设置成1。这与ADDS指令中的进位指令正好相反。这主要是为了适应SBC等指令的操作需要。

8、RSC带位逆向减法指令
指令的语法格式:
RSC{}{S} , ,

指令操作的伪代码:
if ConditionPassed(cond) then
Rd = shifter_operand - Rn - 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(shifter_operand - Rn -NOT(C Flag))
V Flag = OverflowFrom(shifter_operand - Rn - NOT(C Flag))

指令的使用:
下面的指令序列可以求一个64位数值的负数。64位数放在寄存器R0与R1中,其负数放在R2和R3中。其中R0与R2中放低32位值。
RSBS R2, R0, #0
SBC R3, R1, #0
需要注意的是,在RSBS 指令中,如果发生了借位操作,CPSR寄存器中的C标志位设置成0;如果没有发生借位操作,CPSR寄存器中的C标志位设置成1。这与ADDS指令中的进位指令正好相反。

9、AND逻辑与操作指令
指令的格式:
AND{}{S} , ,

指令操作的伪代码:
if ConditionPassed(cond) then
Rd = Rn AND 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

10、ORR逻辑或操作指令
指令的语法格式:
ORR{}{S} , ,

指令操作的伪代码:
if ConditionPassed(cond) then
Rd = Rn OR 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

11、EOR逻辑异或指令

指令的语法格式:

EOR{}{S} , ,

指令操作的伪代码:

if ConditionPassed(cond) then

Rd = Rn EOR 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


12、BIC位清除指令

指令的语法格式:

BIC{}{S} , ,


指令操作的伪代码:

if ConditonPassed(cond) then

Rd = Rn AND NOT 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

指令的使用:

BIC指令可用于将寄存器中某些位的值设置成0.将某些位与1做BIC操作,该位被设置为0,将某一位与0做BIC操作,该位值不变。


13、CMP比较指令

指令的语法格式:

CMP{} ,


指令操作的伪代码:

if ConditionPassed(cond) then

alu_out = Rn - shifter_operand

N Flag = alu_out[31]

Z Flag = if alu_out == 0 then 1 else 0

C FLag = NOT BorrowFrom(Rn - shifter_operand)

V Flag = OverflowFrom(Rn - shifter_operand)


14、CMN基于相反数的比较指令

指令的语法格式:

CMN{} ,


指令操作的伪代码:

alu_out = Rn + shifter_operand

N Flag = alu_out[31]

Z Flag = if alu_out == 0 then 1 else 0

C FLag = NOT BorrowFrom(Rn + shifter_operand)

V Flag = OverflowFrom(Rn + shifter_operand)

指令的使用:

CMN指令将寄存器中的值加上表示的数据,根据加法操作的结果设置CPSR中相应的条件标志位。寄存器中的值加上表示的数值对CPSR中条件标志位的影响,与寄存器中的数值减去表示的数值的相反数对CPSR中条件标志位的影响有细微的差别。当第二个操作数为0或者0x80000000时二者结果不同,如:

CMP Rn, #0 ; C = 1

CMN Rn, #0 ; C = 0


15、TST未测试指令

指令的语法格式:

TST{} ,


指令操作的伪代码:

if ConditionPassed(cond) then

alu_out = Rn AND shifter_operand

N Flag = alu_out[31]

Z Flag = if alu_out == 0 then 1 else 0

C Flag = shifter_carry_out

V Flag = unaffected


指令的使用

TST指令通常用于测试寄存器中某个(些)位是0还是1。


16、TEQ相等测试指令

指令的语法格式:

TEQ{} ,


指令操作的伪代码:

if ConditionPassed(cond) then

alu_out = Rn EOR shifter_operand

N Flag = alu_out[31]

Z Flag = if alu_out == 0 then 1 else 0

C Flag = shifter_carry_out

V Flag = unaffected


指令的使用:

TEQ指令通常用于比较两个数是否相等,这种比较操作通常不影响CPSR寄存器的V位和C位

TEQ指令也可以用于比较两个操作数符号是否相同,该指令执行后,CPSR寄存器中的N位为两个操作数符号位作异或操作的结果。

你可能感兴趣的:(编程语言)