ARM指令系统总结
标签:
育儿学习小笔记arm |
分类: ARM学习笔记 |
ARM指令集
6种类型(53种主要助记符) :
数据处理指令(22种主要助记符)
跳转指令(4种主要助记符)
Load/Store指令(16种主要助记符)
程序状态寄存器指令(2种主要助记符)
协处理器指令(5种主要助记符)
软件中断指令 (2种主要助记符)
数据处理指令
数据处理指令大致可分为3类:
数据传送指令;
算术逻辑运算指令;
乘法指令
比较指令。
数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。所有ARM数据处理指令均可选择使用S后缀,并影响状态标志。
数据处理指令1
MOV 数据传送指令
格式:MOV{}{S} ,;
功能:Rd=op1
op1可以是寄存器、被移位的寄存器或立即数。
例如:
MOV R0,#5 ;R0=5
MOV R0,R1 ;R0=R1
MOV R0,R1,LSL#5 ;R0=R1左移5位
数据处理指令2
2.MVN 数据取反传送指令
格式:MVN{}{S} ,;
功能:将op1表示的值传送到目的寄存器Rd中,但该值在传送前被按位取反,即Rd=!op1;
op1可以是寄存器、被移位的寄存器或立即数。
例如:
MVN R0,#0 ;R0=-1
数据处理指令3
3.ADD 加法指令
格式:ADD{}{S} ,,;
功能:Rd=Rn+op2
op2可以是寄存器,被移位的寄存器或立即数。
例如:
ADD R0,R1,#5 ;R0=R1+5
ADD R0,R1,R2 ;R0=R1+R2
ADD R0,R1,R2,LSL#5 ;R0=R1+R2左移5位
数据处理指令4
4.ADC 带进位加法指令
格式:ADC{}{S} ,,;
功能:Rd=Rn+op2+carry
op2可以是寄存器、被移位的寄存器或立即数;carry为进位标志值。该指令用于实现超过32位的数的加法。
例如:
第一个64位操作数存放在寄存器R2,R3中;
第二个64位操作数存放在寄存器R4,R5中;
64位结果存放在R0,R1中。
64位的加法可由以下语句实现:
ADDS R0,R2,R4 ;低32位相加,S表示结果影响条件标志位的值
ADC R1,R3,R5 ;高32位相加
数据处理指令5
5.SUB 减法指令
格式:SUB{}{S} ,,;
功能:Rd=Rn-op2
op2可以是寄存器、被移位的寄存器或立即数。
例如:
SUB R0,R1,#5 ;R0=R1-5
SUB R0,R1,R2 ;R0=R1-R2
SUB R0,R1,R2,LSL#5 ;R0=R1-R2左移5位
数据处理指令6
6.RSB 反向减法指令
格式:RSB{}{S} ,,;
功能:同SUB指令,但倒换了两操作数的前后位置,即Rd=op2-Rn。
例如:
RSB R0,R1,#5 ;R0=5-R1
RSB R0,R1,R2 ;R0=R2-R1
RSB R0,R1,R2,LSL#5 ;R0=R2左移5位-R1
数据处理指令7
7.SBC 带借位减法指令
格式:SBC{}{S} ,,;
功能:Rd=Rn-op2-!carry
op2可以是寄存器、被移位的寄存器或立即数。
SUB和SBC生成进位标志的方式不同于常规,如果需要借位则清除进位标志,所以指令要对进位标志进行一个非操作。
例如:
第一个64位操作数存放在寄存器R2,R3中;
第二个64位操作数存放在寄存器R4,R5中;
64位结果存放在R0,R1中。
64位的减法(第一个操作数减去第二个操作数)可由以下语句实现:
SUBS R0,R2,R4; 低32位相减,S表示结果影响条件标志位的值
SBC R1,R3,R5; 高32位相减
数据处理指令8
8.RSC 带借位的反向减法指令
格式:RSC{}{S} ,,;
功能:同SBC指令,但倒换了两操作数的前后位置,即Rd=op2-Rn-!carry。
例如:
前提条件与SBC例子相同,操作数1-操作数2的实现语句需改为:
SUBS R0,R2,R4; 低32位相减,S表示结果影响寄存器CPSR的值
RSC R1,R5,R3; 高32位相减
数据处理指令——乘法指令
ARM7TDMI具有三种乘法指令,分别为:
32×32位乘法指令;
32× 32位乘加指令;
32× 32位结果为64位的乘/乘加指令。
数据处理指令9
9.MUL 32位乘法指令
格式:MUL{}{S} ,,;
功能:Rd=Rn×op2
该指令根据S标志,决定操作是否影响CPSR的值;其中op2必须为寄存器。Rn和op2的值为32位的有符号数或无符号数。
例如:
MULS R0,R1,R2 ;R0=R1×R2,结果影响寄存器CPSR的值
数据处理指令10
10.MLA 32位乘加指令
格式:MLA{}{S} ,,,;
功能:Rd=Rn×op2+op3
op2和op3必须为寄存器。Rn、op2和op3的值为32位的有符号数或无符号数。
例如:
MLA R0,R1,R2,R3 ;R0=R1×R2+R3
数据处理指令11
11.SMULL 64位有符号数乘法指令
格式:
SMULL{}{S} ,,,;
功能:Rdh Rdl=Rn×op2
Rdh、Rdl和op2均为寄存器。Rn和op2的值为32位的有符号数。
例如:
SMULL R0,R1,R2,R3
;R0=R2×R3的低32位
;R1=R2×R3的高32位
数据处理指令12
12.SMLAL 64位有符号数乘加指令
格式:
SMLAL{}{S} ,,,;
功能:Rdh Rdl=Rn×op2+Rdh Rdl
Rdh、Rdl和op2均为寄存器。Rn和op2的值为32位的有符号数,Rdh Rdl的值为64位的加数。
例如:
SMLAL R0,R1,R2,R3
;R0=R2×R3的低32位+R0
;R1=R2×R3的高32位+R1
数据处理指令13
13.UMULL 64位无符号数乘法指令
格式:
UMULL{}{S} ,,,;
功能:同SMULL指令,但指令中Rn和op2的值为32位的无符号数。
例如:
UMULL R0,R1,R2,R3
;R0=R2×R3的低32位
;R1=R2×R3的高32位
其中R2,R3的值为无符号数
数据处理指令14
14.UMLAL 64位无符号数乘加指令
格式:
UMLAL {}{S} ,,,;
功能:同SMLAL指令,但指令中Rn,op2的值为32位的无符号数,Rdh Rdl的值为64位无符号数。
例如:
UMLAL R0,R1,R2,R3
;R0=R2×R3的低32位+R0
;R1=R2×R3的高32位+R1
其中R2,R3的值为32位无符号数
R1,R0的值为64位无符号数
数据处理指令15
15.AND 逻辑与指令
格式:AND{}{S} ,,;
功能:Rd=Rn AND op2
op2可以是寄存器,被移位的寄存器或立即数。一般用于清除Rn的特定几位。
例如:
AND R0,R0,#5
;保持R0的第0位和第2位,其余位清0
数据处理指令16
16.ORR 逻辑或指令
格式:ORR{}{S} ,,;
功能:Rd=Rn OR op2
op2可以是寄存器、被移位的寄存器或立即数。一般用于设置Rn的特定几位。
例如:
ORR R0,R0,#5
;R0的第0位和第2位设置为1,其余位不变
数据处理指令17
17.EOR 逻辑异或指令
格式:EOR{}{S} ,,;
功能:Rd=Rn EOR op2
op2可以是寄存器、被移位的寄存器或立即数。一般用于将Rn的特定几位取反。
例如:
EOR R0,R0,#5
;R0的第0位和第2位取反,其余位不变
数据处理指令18
18.BIC 位清除指令
格式:BIC{}{S} ,,;
功能:Rd=Rn AND (!op2)
用于清除寄存器Rn中的某些位,并把结果存放到目的寄存器Rd中.
操作数op2是一个32位掩码(mask),如果在掩码中设置了某一位,则清除Rn中的这一位;未设置的掩码位指示Rn中此位保持不变。其中,op2可以是寄存器、被移位的寄存器或立即数。
例如:
BIC R0,R0,#5
;R0中第0位和第2位清0,其余位不变
数据处理指令19
19.CMP
比较指令
格式:CMP{} ,;
功能:Rn-op1
该指令进行一次减法运算,但不存储结果,根据结果更新CPSR中条件标志位的值。
该指令不需要显式地指定S后缀来更改状态标志。其中,操作数op1为寄存器或立即数。
例如:
CMP
ADDGT R0, R0,
#5;
数据处理指令20
20.CMN 反值比较指令
格式:CMN{} ,;
功能:同CMP指令,但寄存器Rn的值是和op1取负的值进行比较。
例如:
CMN R0,#5 ;把R0与-5进行比较
数据处理指令21
21.TST 位测试指令
格式:TST{} ,;
功能: Rn AND op1
根据结果更新CPSR中条件标志位的值,但不存储结果。
用于检查寄存器Rn是否设置了op1中相应的位。
例如:
TST R0,#5
;测试R0中第0位和第2位是否为1
数据处理指令22
22.TEQ 相等测试指令
格式:TEQ{} ,;
功能: Rn EOR op1
将寄存器Rn的值和操作数op1所表示的值按位作逻辑异或操作,根据结果更新CPSR中条件标志位的值,但不存储结果。
用于检查寄存器Rn的值是否和op1所表示的值相等。
例如:
TEQ R0,#5 ;判断R0的值是否和5相等
跳转指令
跳转指令用于实现程序的跳转和程序状态的切换。
ARM程序设计中,实现程序跳转有两种方式:
(1)跳转指令,
(2)直接向程序寄存器PC(R15)中写入目标地址值。
通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转。
使用跳转指令,其跳转空间受到限制。
跳转指令1
1.B 跳转指令
格式:B{} ;
功能: PC= PC+ addr左移两位
addr的值是相对当前PC(即寄存器R15)的值的一个偏移量,而不是一个绝对地址,它是24位有符号数。实际地址的值由汇编器来计算.
addr的值有符号扩展为32位后,左移两位,然后与PC值相加,即得到跳转的目的地址。
跳转的范围为-32MB~+32MB。
例如:
B exit; 程序跳转到标号exit处
…exit…
跳转指令2
2.BL 带返回的跳转指令
格式:BL{} ;
功能:同B指令,但BL指令执行跳转操作的同时,还将PC(寄存器R15)的值保存到LR寄存器(寄存器R14)中。
该指令用于实现子程序调用,程序的返回可通过把LR寄存器的值复制到PC寄存器中来实现。
例如:
BL func; 调用子程序func
…
func
…
MOV R15,R14; 子程序返回
由于返回地址保存在寄存器里,在保存R14之前不应再调用下一级的嵌套子程序;否则,新的返回地址将覆盖原来的返回地址,就无法返回到原来的调用位置。这时一般是把R14压入存储器中的堆栈。由于子程序经常还需要一些工作寄存器,所以可使用多寄存器存储指令同时把这些寄存器中原有的数据一起存储。
例如:
BL SUB1
…
SUB1 STMFD R13!,{R0-R2,R14};保存工作和链接寄存器
BL SUB2
…SUB2…
对于不调用其他子程序的子程序(叶子程序),不需要保存R14,因为它不会被覆盖。
跳转指令3
3.BLX 带返回和状态切换的跳转指令
格式:BLX ;或BLX ;
功能:处理器跳转到目标地址处,并将PC(寄存器R15)的值保存到LR寄存器(R14)中。
若为第二种格式,寄存器Rn的值是转移目标,Rn的第0位拷贝到CPSR中的T位(决定是继续执行还是切换到Thumb指令),[31:0]位移入PC;
如果Rn[0]是1,则处理器切换执行Thumb指令,并在Rn中的地址开始执行,但是需将最低为清零;如果Rn[0]是0,则处理器继续执行ARM指令,并在Rn中的地址处开始执行,但需将Rn[1]清零。
该指令用于子程序调用和程序状态的切换。
例如:
BLX T16; 跳转到标号T16处执行,T16后面的指令为Thumb指令
…
CODE16
T16 后面指令为Thumb指令
…
跳转指令4
4.BX 带状态切换的跳转指令
格式:BX ;
功能:处理器跳转到目标地址处,从那里继续执行;
目标地址为寄存器Rn的值和0xFFFFFFFE作与操作的结果。
目标地址处的指令可以是ARM指令,也可以是Thumb 指令。
例如:
ADR R0,exit ;标号exit处的地址装入R0中
BX R0 ;跳转到exit处
条件执行的举例
将流程图对应GCD算法转换成
1) 普通汇编代码
2)ARM 汇编代码.
只使用 CMP, B 及 SUB指令
http://www.eefocus.com/data/08-07/4155_1217334535/1217912398.jpg
条件执行的举例
普通汇编代码
gcd cmp r0, r1 ;reached the end?
beq stop
blt less ;if r0 > r1
sub r0, r0, r1 ;subtract r1 from r0
bal gcd
less sub r1, r1, r0 ;subtract r0 from r1
bal gcd
stop
ARM 代码
gcd cmp r0, r1 ;if r0 > r1
subgt r0, r0, r1 ;subtract r1 from r0
sublt r1, r1, r0 ;else subtract r0 from r1
bne gcd ;

加载中…