本文主要是介绍ARM指令集——数据处理指令篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
输出传送指令包括以下指令:
- MOV 数据传送指令
- MVN 数据求反传送指令
- CMP 比较指令
- CMV 基于相反数的比较指令
- TST 位测试指令
- TEQ 相等测试指令
- ADD 加法指令
- SUB 减法指令
- RSB 逆向减法指令
- ADC 带位加法指令
- SBC 带位减法指令
- RSC 带位逆向减法指令
- AND 安位与指令
- BIC 为清零指令
- EOR 逻辑异或指令
- ORR 逻辑或指令
下面分别作详细介绍:
1、MOV传送指令
指令的语法格式:
MOV{<cond>}{S} <Rd>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
操作指令的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>} <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>} <Rn>, <shifter_operand>
指令操作的伪代码:
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指令将寄存器<Rn>中的值加上<shifter_operand>表示的数据,根据加法操作的结果设置CPSR中相应的条件标志位。寄存器<Rn>中的值加上<shifter_operand>表示的数值对CPSR中条件标志位的影响,与寄存器<Rn>中的数值减去<shifter_operand>表示的数值的相反数对CPSR中条件标志位的影响有细微的差别。当第二个操作数为0或者0x80000000时二者结果不同,如:
CMP Rn, #0 ; C = 1
CMN Rn, #0 ; C = 0
15、TST未测试指令
指令的语法格式:
TST{<cond>} <Rn>, <shifter_operand>
指令操作的伪代码:
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{<cond>} <Rn>, <shifter_operand>
指令操作的伪代码:
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位为两个操作数符号位作异或操作的结果。
这篇关于ARM指令集——数据处理指令篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!