本文声明:内容来源于网络,进行整合/再创作;部分内容由AI辅助生成。
Tips:本节知识分为上、下篇讲述,可通过专栏查找到对应文章。本节主要讲述一些比较常用且简单的ARM指令集,对于一些使用频率较低、复杂的ARM指令不做过多的介绍,初学者能够看懂基本的汇编语言即可。主要是针对AArch64指令集(ARMv8‑A架构),Xn表示64位寄存器,Wn表示32位寄存器(类似于Rn),部分AArch64指令集与AArch32类似(看指令举例有无Wn,有就表示AArch32指令集也是类似写法)。笔者不精通该部分知识,因此不确保内容完全准确。
数据处理指令
数据处理指令是指对存放在寄存器中的数据进行操作的指令,主要包括数据传输指令、算术运算指令、逻辑运算指令、比较指令、移位运算指令和整数乘法/除法指令。

1、数据传输指令
MOV (Move)指令是最简单的ARM指令,执行的结果就是把一个数送到目标寄存器 (N可以是立即数或寄存器)。数据传输指令多用于设置初始值 或在寄存器间传输数据。
指令举例:
MOV W6, #0xFFFF ; W6 = 0xFFFF
MOV W7, W6, LSL #4 ; W7 = (W6 << 4)
MOV X6, #0xFFFFFFFF ; X6 = 0xFFFFFFFF
MOV X7, W6, LSL #4 ; X7 = (X6 << 4)
MVN:取反传输。
2、算术运算指令
算术运算指令主要用于数学运算相关操作。ARM指令集中的算术运算指令主要用于两个数之间的运算。
ADD/ADDS指令(加法)
ADD(Addition)/ADDS指令用于将两个数相加,并将结果保存到目标寄存器中。其中,ADDS指令的执行结果会影响PSTATE.NZCV状态位。
指令举例:
ADD W2, W1, #0xFF ; W2 = W1 + 0xFF
ADDS W2, W1, #0xFF ; W2 = W1 + 0xFF,如果产生进位,C位自动置1
ADD X2, X1, X0 ; X2 = X1 + X0
ADDS X2, X1, X0, LSL#4 ; X2 = X1 + (X0 << 4),如果产生进位,C位自动置1
SUB/SUBS指令(减法)
SUB(Subtract)/SUBS指令用于将两个数相减,并将结果保存到目标寄存器中。其中,SUBS指令的执行结果会影响PSTATE.NZCV状态位。
指令举例:
SUB W2, W1, #0xFF ; W2 = W1 - 0xFF
SUBS W2, W1, #0xFF ; W2 = W1 - 0xFF,如果产生进位,C位自动清0
SUB X2, X1, X0 ; X2 = X1 - X0
SUBS X2, X1, X0, LSL #4 ; X2 = X1 - (X0 << 4),如果产生进位,C位自动清0
3、逻辑运算指令
逻辑运算指令主要用于逻辑运算及逻辑表达式的实现。
AND/ANDS指令(按位与)
AND/ANDS指令将两个数进行按位逻辑与运算,并将结果保存到目标寄存器中。其中,ANDS指令根据结果设置N和Z条件标志位,并清除C和V条件标志位。
指令举例:
AND W0, W1, #0xFF ; W0 = W1 & 0xFF
ANDS W0, W1, #0xFF ; W0 = W1 & 0xF,根据结果设置N和Z条件标志位,并清除C和V条件标志位
AND X2, X1, X0, LSL #4 ; X2 = X1 & (X0 << 4)
ORR指令(按位或)
ORR(InclusiveOR)指令将两个数进行按位逻辑或运算,并将结果保存到目标寄存器中。注意,没有ORRS指令。
指令举例:
ORR W4, W3, #0x0F ; W4 = W3 | 0x0F
ORR X6, X5, X4, LSL #4 ; X6 = X5 | (X4 << 4)
EOR指令(按位异或)
EOR(ExclusiveOR)指令将两个数据进行按位异或运算,并将执行结果保存到目的寄存器中。注意同样没有EORS指令。
指令举例:
EOR W4, W3, #0x0F ; W4 = W3 ^ 0x0F
EOR X6, X5, X4, LSL #4 ; X6 = X5 ^ (X4 << 4)
BIC/BICS指令(位清零)
BIC(Bit Clear)位清零指令将第一个操作寄存器的值与第二个操作数的反码按位 进行逻辑与运算,并将执行结果保存到目标寄存器中。其中,BICS指令根据结果设置N和Z条件标志位,并清除C和V条件标志位。
指令举例:
BIC W4, W4, #0x0F ; W4 = W3 & ~0xFF
BIC X6, X5, X4, LSL #4 ; X6 = X5 & ~(X4 << 4)
BICS W4, W4, W2 ; W4 = W3 & ~W2,根据结果设置N和Z条件标志位,并清除C和V条件标志位
4、比较指令
比较指令是ARM指令集中一类非常重要的指令,主要用于实现条件判断 、程序的分支处理,条件指令常跟条件码一起出现使用。
CMP指令
CMP(Compare)指令的本质是将两个数相减,根据运算的结果更新PSTATE.NZCV条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。
CMP指令允许把一个寄存器的值与另一个寄存器的值或立即值进行比较,更改状态标志来允许进行条件执行。它进行一次减法,但不存储结果 ,而是更改标志位。标志位表示的是操作数1与操作数2比较的结果(其值可能为大于、小于、等于)。如果操作数1大于操作数2,则对应的条件码是GT。CMP不需要显式地指定后缀S来更改状态标志。
指令举例:
CMP W0, #10 ; 将W0的值与立即数10比较,即执行W0-10的减法运算(结果丢弃),并根据运算结果更新N/Z/C/V条件标志位
CMP X0, X1, LSL#4 ; 将X0的值与X1的值逻辑左移4位后的结果进行比较,即先执行X1<<4,再执行X0-(X1<<4),运算结果丢弃,仅更新N/Z/C/V条件标志位
BEQ label ; 假如相等,则跳转到label
CMP指令与SUBS指令的区别在于CMP指令不保存运算结果,在进行两个数据大小的判断时,常用CMP指令和相应的条件码来进行操作。
CMN指令
CMN(Compare Negative)指令本质是做加法运算 ,根据运算的结果(不保存)更新PSTATE.NZCV条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。
CMN指令将第一个寄存器中的值加上第二个寄存器或立即数的值,根据加法的结果设置PSTATE.NZCV条件标志位,常用于判断一个数是否是另一个数的相反数。
指令举例:
CMN W0, #10 ; 把W0的值和-10比较(等价于检查W0+10是否等于0),仅更新标志位
CMN X0, X1, LSL#4 ; 把X0的值和-(X1左移4位)比较(等价于检查X0+(X1<<4)是否等于0),仅更新标志位