ARM 汇编指令学习:[2]ARM指令集
一、跳转指令
1、 B(跳转指令)及BL(带返回跳转指令)
B{L}{<cond>} <target_address>
其中:
L 决定是否保存当前PC寄存器地址到LR寄存器中。
<target_address> 为指令跳转的目标地址。这个地址的计算方法是:将指令中的24位带符号的补码立即数扩展为32位(扩展其符号位);将此32位数左移两位;将得到的值加到PC寄存器中,即得到跳转的目标地址。由这种计算方法可知跳转的范围大致为-32MB~+32MB。
2、 第一种BLX(带返回和状态切换的跳转指令)
BLX <target_address>
其中,<target_address>的用法与B及BL指令中的用法相同。
3、 第二种BLX(带返回和状态切换的跳转指令)
BLX{<cond>} <Rm>
其中:
<Rm> 该寄存器中为跳转的目标地址。当<Rm>寄存器的bit[0]值为0时,目标地址处的指令为ARM指令;当<Rm>寄存器的bit[0]值为1时,目标地址处的指令为Thumb指令。当<Rm>寄存器为R15(PC)时,会产生不可预知的结果(跑飞)。
4、 BX(带状态切换的跳转指令)
BX{<cond>} <Rm>
其中,<Rm>的用法与BLX指令中的用法相同。
二、数据处理指令
1、 MOV 数据传送指令
MOV{<cond>}{S} <Rd>, <shifter_operand>
MOV指令将<shifter_operand>表示的数据传送到目标寄存器<Rd>中,并根据操作的结果更新CPSR中相应的条件标志位。
2、 MVN 数据求反传送指令
MVN{<cond>}{S} <Rd>, <shifter_operand>
MVN指令将<shifter_operand>表示的数据的反码传送到目标寄存器<Rd>中,并根据操作的结果更新CPSR中相应的条件标志位。
3、 CMP 比较指令
CMP{<cond>} <Rn>, <shifter_operand>
CMP指令从寄存器<Rn>中减去<shifter_operand>表示的数据,并根据操作的结果更新CPSR中相应的条件标志位,后面的指令就可以根据CPSR中相应的条件标志位来判断是否执行。
4、 CMN 基于相反数的比较指令
CMN{<cond>} <Rn>, <shifter_operand>
CMN指令从寄存器<Rn>中加上<shifter_operand>表示的数据,并根据操作的结果更新CPSR中相应的条件标志位,后面的指令就可以根据CPSR中相应的条件标志位来判断是否执行。
5、 TST 位测试指令
TST{<cond>} <Rn>, <shifter_operand>
TST指令将<shifter_operand>表示的数据与寄存器<Rn>的值按位作逻辑与操作,并根据操作的结果更新CPSR中相应的条件标志位,后面的指令就可以根据CPSR中相应的条件标志位来判断是否执行。
6、 TEQ 相等测试指令
TEQ{<cond>} <Rn>, <shifter_operand>
TEQ指令将<shifter_operand>表示的数据与寄存器<Rn>的值按位作逻辑异或操作,并根据操作的结果更新CPSR中相应的条件标志位,后面的指令就可以根据CPSR中相应的条件标志位来判断是否执行。
7、 ADD 加法指令
ADD{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
ADD指令将<shifter_operand>表示的数据的与<Rn>的值相加,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
8、 SUB 减法指令
SUB{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
SUB指令从寄存器<Rn>中减去<shifter_operand>表示的数据,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
9、 RSB 逆向减法指令
RSB{<cond> }{S} <Rd>, <Rn>, <shifter_operand>
RSB指令从<shifter_operand>表示的数据中减去寄存器<Rn>的值,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
10、 ADC 带位加法指令
ADC{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
ADC指令将<shifter_operand>表示的数据的与<Rn>的值相加,再加上寄存器CPSR中的C条件标志位的值,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
11、 SBC 带位减法指令
SBC{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
SBC指令从寄存器<Rn>中减去<shifter_operand>表示的数据,再减去寄存器CPSR中的C条件标志位的反码,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
12、 RSC 带位逆向减法指令
RSC{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
RSC指令从<shifter_operand>表示的数据中减去寄存器<Rn>的值,再减去寄存器CPSR中的C条件标志位的反码,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
13、 AND 逻辑与操作指令
AND{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
AND指令将<shifter_operand>表示的数据与寄存器<Rn>的值按位作逻辑与操作,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
14、 BIC 位清除指令
BIC{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
BIC指令将<shifter_operand>表示的数据与寄存器<Rn>的反码按位作逻辑与操作,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
15、 EOR 逻辑异或操作指令
EOR{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
EOR指令将<shifter_operand>表示的数据与寄存器<Rn>的值按位作逻辑异或操作,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
16、 ORR 逻辑或操作指令
ORR{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
ORR指令将<shifter_operand>表示的数据与寄存器<Rn>的值按位作逻辑或操作,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。
17、 乘法指令
- MUL 32位乘法指令
MUL{<cond>}{S} <Rd>, <Rm>, <Rs>
示例
MUL R0, R1, R2 ; R0=R1*R2
- MLA 32位带加数的乘法指令
MLA{<cond>}{S} <Rd>, <Rm>, <Rs>, <Rn>
示例
MLA R0, R1, R2, R3 ; R0=R1*R2+R3
- SMULL 64位有符号数乘法指令
SMULL{<cond>}{S} <RdLo>, <RdHi>, <Rm>, <Rs>
示例
SMULL R1, R2, R3, R4 ; R1=R3*R4的低32位;R2=R3*R4的高32位
- SMLAL 64位带加数的有符号数乘法指令
SMLAL{<cond>}{S} <RdLo>, <RdHi>, <Rm>, <Rs>
示例
SMLAL R1, R2, R3, R4 ; R1=R3*R4的低32位+R1;R2=R3*R4的高32位+R2
- UMULL 64位无符号数乘法指令
UMULL{<cond>}{S} <RdLo>, <RdHi>, <Rm>, <Rs>
- UMLAL 64位带加数的无符号数乘法指令
UMLAL{<cond>}{S} <RdLo>, <RdHi>, <Rm>, <Rs>
18、 杂类的算术指令
- CLZ 前导0个数计数指令
CLZ{<cond>} <Rd>, <Rm>
CLZ指令用于计算寄存器中操作数最高端的0的个数。如果操作数的bit[31]为1,则指令返回0;如果操作数为0,则指令返回32。
三、程序状态寄存器(PSR)传输指令
1、 MRS 状态寄存器到通用寄存器的传送指令
MRS{<cond>} <Rd>, CPSR
MRS{<cond>} <Rd>, SPSR
2、 MSR 通用寄存器到状态寄存器的传送指令
MSR{<cond>} CPSR_<fields>, #<immediate>
MSR{<cond>} CPSR_<fields>, <Rm>
MSR{<cond>} SPSR_<fields>, #<immediate>
MSR{<cond>} SPSR_<fields>, <Rm>
四、Load/Store指令
- LDR
- LDRB
- LDRBT
- LDRH
- LDRSB
- LDRSH
- LDRT
- STR
- STRB
- STRBT
- STRH
- STRSB
- STRSH
- STRT
- ......
详见我的上一篇文章。
信号量操作指令
- SWP 交换指令
SWP{<cond>} <Rd>, <Rm>, [<Rn>]
示例
SWP R1, R2, [R3] ; 将内存单元(R3)中的字数据读取到R1寄存器中,同时将R2寄存器的数据写入到内存单元(R3)中
- SWPB 字节交换指令
SWPB{<cond>} <Rd>, <Rm>, [<Rn>]
示例
SWPB R1, R2, [R3] ; 将内存单元(R3)中的字节数据读取到R1寄存器中,R1的高24位为0,同时将R2寄存器的低8位写入到内存单元(R3)中
五、协处理器指令
1、 CDP 协处理器数据操作指令
CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
本指令是ARM处理器用于通知ARM协处理器执行特定的操作。该操作不涉及ARM寄存器和内存单元。
示例
CPD p5, 2, c12, c10, c3, 4 ; 协处理器p5的操作初始化。其中,操作码1为2,操作码2为4,目标寄存器为c12,源操作寄存器为c10和c3
2、 LDC 协处理器数据读取指令
LDC{<cond>}{L} <coproc>, <CRd>, <addressing_mode>
LDC2{L} <coproc>, <CRd>, <addressing_mode>
LDC指令从一系列连续的内存单元将数据读取到协处理器的寄存器中。
示例
LDC p6, CR4, [R2, #4] ; R2为ARM处理器,指令读取内存单元(R2+4)的字数据,传送到协处理器p6的CR4寄存器中
3、 STC 协处理器数据写入指令
STC{<cond>}{L} <coproc>, <CRd>, <addressing_mode>
STC2{L} <coproc>, <CRd>, <addressing_mode>
STC指令将协处理器的寄存器中的数据写入到一系列连续的内存单元中。
示例
STC p6, CR4, [R2, #4] ; R2为ARM处理器,指令将协处理器p6的CR4寄存器中的字数据写入到内存单元(R2+4)中
4、 MCR ARM寄存器到协处理器寄存器的数据传送指令
MCR{<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。
示例
MCR p14, 3, R7, c7, c11, 6 ; 指令将ARM寄存器中将数据传送到协处理器p14的寄存器中,其中R7为ARM处理器,存放源操作数;C7和C11为协处理器寄存器,为目标寄存器;操作码1为3,操作码2为6
5、 MRC 协处理器寄存器到ARM寄存器的数据传送指令
MRC{<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
MRC指令将协处理器的寄存器中的数据传送到ARM处理器的寄存器中。
示例
MRC p14, 3, R7, c7, c11, 6 ; 指令将协处理器p14的寄存器中将数据传送到ARM寄存器中,其中R7为ARM处理器,为目标寄存器;C7和C11为协处理器寄存器,存放源操作数;操作码1为3,操作码2为6
六、异常中断产生指令
1、 SWI 软中断指令
SWI{<cond>} <immed_24>
SWI指令用于产生软中断。
2、 BKPT 断点中断指令
BKPT <immed_16>
BKPT指令用于产生软件断点中断。软件调试程序可以使用该中断。当系统使用硬件调试部件时可以忽略该中断。
参考自《ARM体系架构与编程》杜春雷
- 我的个人主页:http://www.techping.cn/
- 我的个人站点博客:http://www.techping.cn/blog/wordpress/
- 我的CSDN博客:http://blog.csdn.net/techping
- 我的简书:http://www.jianshu.com/users/b2a36e431d5e/timeline
- 我的GitHub:https://github.com/techping
欢迎相互follow~