接着上文,接着讲一下算术与移位指令,想要系统学习arm64指令的朋友们,添加一个关注,后面会持续更新的
普通的加法指令有下面几种用法。
使用立即数的加法。
使用寄存器的加法。
使用移位操作的加法。
1、使用立即数的加法指令
ADD ,,#{,}
它的作用是把Xn/SP寄存器的值再加上立即数imm(0~4095),把结果写入Xd/SP寄存器里。Shift为0或12
2、使用寄存器的加法指令
ADD ,,{, {#}}
这条指令的作用是先把Rm寄存器做一些扩展,例如左移操作,然后再加上Xn/SP寄存器的值,把结果写入Xd/SP寄存器中
3、使用移位操作的加法指令
ADD , , {, #}
这条指令的作用是先把Xm寄存器做一些移位操作,然后再加上Xn寄存器的值,结果写入Xd寄存器中。amount 0~63
4、ADDS指令
ADDS指令是ADD指令的变种,唯一的区别是指令执行结果会影响PSTATE寄存器的N、Z、C、V标志位,例如当计算结果发生无符号数溢出时,C=1。
5、ADC指令
ADC , ,
Xd寄存器的值等于Xn寄存器的值加上Xm寄存器的值加上C,其中C表示PSTATE寄存器的C标志位。
普通的减法指令与加法指令类似,也有下面几种用法。
使用立即数的减法。
使用寄存器的减法。
使用移位操作的减法。
1、使用立即数的减法指令
SUB , , #{, }
把Xn/SP寄存器的值减去立即数imm,结果写入Xd/SP寄存器里。shift取值为0或12
2、使用寄存器的减法指令
SUB , , {, {#}}
指令的作用是先对Rm寄存器做一些扩展,例如左移操作,然后Xn/SP寄存器的值减Rm寄存器的值,把结果写入Xd/SP寄存器中。
3、使用移位操作的减法指令
SUB , , {, {#}}
先把Xm寄存器做一些移位操作,然后使Xn寄存器中的值减去Xm寄存器中的值,把结果写入Xd寄存器中。
4、SUBS指令
SUBS指令是SUB指令的变种,唯一的区别是指令执行结果会影响PSTATE寄存器的N、Z、C、V标志位。SUBS指令判断是否影响N、Z、C、V标志位的方法比较特别,
5、SBC指令
SBC是进位的减法指令,也就是最终的计算结果需要考虑PSTATE寄存器的C标志位。SBC指令的格式如下
SBC , ,
SBC指令的计算过程是,首先对第二个操作数做取反操作,然后把第一个操作数、第二个操作数相加,这个过程会影响PSTATE寄存器的C标志位,最后把C标志位加上。
SBC指令的计算公式为 Xd = Xn + NOT(Xm) + C
CMP指令用来比较两个数的大小。在A64指令集的实现中,CMP指令内部调用SUBS指令来实现。
1.使用立即数的CMP指令
CMP , #{,}
2.使用寄存器的CMP指令
使用寄存器的CMP指令的格式如下。
CMP , {, {#}}
3、使用移位操作的CMP指令
CMP ,{, #}
4.CMP指令与条件操作后缀
CMP指令常常和跳转指令与条件操作后缀搭配使用,例如条件操作后缀CS表示是否发生了无符号数溢出,即C标志位是否置位,CC表示C标志位没有置位。
cmp x1 , x2
b.cs label
LSL 逻辑左移LSR 逻辑右移ASR 算术右移指令,最高位按照符号进行扩展ROR 循环右移指令
1、AND指令
AND , , #AND , , {,} shift表示移位操作,amount 0~63
2、ANDS指令
ANDS , , #ANDS , , {,} shift表示移位操作
与AND指令不一样的地方是它根据计算结果来影响PSTATE寄存器的N、Z、C、V 标志位
3、或操作指令
ORR , , #ORR , , {,} shift表示移位操作
4、异或指令
EOR , , #EOR , , {,} shift表示移位操作
位清除指令
BIC , , {,} shift表示移位操作
先对Xm进行移位操作,然后再与Xn寄存器的值进行位清除操作,如果在掩码中置了某一位1,则清除这一位。未设置的掩码位保持不变,结果放到Xd寄存器中
CLZ ,
CLZ指令计算为1的最高位前面有几个为0的空位
1、位段插入操作指令
BFI ,,#,#
用Xn寄存器中的Bit[0,width-1]替换Xd寄存器中的Bit[lsb,lsb+width-1];Xd中的其他不变
2、位段提取指令
UBFX ,,#,#
提取Xn中的Bit[lsb,lsb+width-1],然后存储到Xd中