天天看点

ARM64基础6:A64的算术和移位指令

条件操作码

在pstate处理器(对应a32之前是CPSR)状态中有4个条件操作吗NCZV

条件标志位 描述
N 负数标志(上次运算结果为负值,则N=1,否则N=0)
Z 上次运算结果为0
C 对于加法运算,无符号溢出,C=1, 其他不变
V 有符号溢出

普通加法指令add

1.使用寄存器的加法;

2.使用立即数的加法;

3.使用移位操作的加法

adds指令,影响条件标志位c

subs指令,影响条件标志位c

adc指令

带进位的加法指令,

ADC Xd, Xn, Xm //Xd =      

SBC指令

SBC Xd, Xn, Xm //Xd =      

CMP指令

内部用subs指令实现的,影响C标志位

cmp x1,x2 //x1+not(x2)+1      

当x1>=x2,C=1

x1<x2, C=0

练习1:测试C条件标志位

#0
    ldr x1,=0xffffffffffffffff
    mov x2,#3
  
      //test adds, influence C flag
    adds x0,x1,x1  //update C
    adc x3, xzr, xzr 
  
      //test for cmp, if x1>x2 ,C=1 ,or C=0
    cmp      

执行结果如下:

ARM64基础6:A64的算术和移位指令

练习2:cmp和sbc搭配使用

>= arg2, return 0
 * when arg1 < arg2, return 0xffffffffffffffff
 * SBC Rd,Rn,Rm -->Rd = Rn-RM-1+c
 */
.global my_compare_test
my_compare_test:   //param x0,x1, return x0
  cmp      

移位指令

指令 描述
lsl 逻辑左移指令 低位补零
lsr 逻辑右移指令 最高位,永远补零
asr 算数右移 左边补位与符号一致
ror 循环右移 最右位,移动做最左位

按位与操作

AND Xd,Xn  -->Xd = Xd &      

ands影响z比特位

/*
 * ands influence Z flag in pstate
 */
.global my_ands_test
my_ands_test:
  mov x1, #0x3
  mov x2, #0      
ARM64基础6:A64的算术和移位指令

按位或/异或

ORR Xd, Xn  -->Xd = Xd | Xn
EOR Xd, Xn  -->Xd =      
异或的三个特点:

(1)0异或任何数=任何数;

(2)1异或任何数=任何数相反数;

(3)任何数异或自己=0;

异或的几个技巧运用

(1) 使某些位翻转:

0xffff,ffff ^ 0x1<<5      

(2) 交换两个数

a = a^b
b = b^a
a =      

(3) 在汇编里设置0

eor x0,x0      

(4) 判断两个数是否相等

return ((a^b)==0)      

按位清除

bic:位清零指令

mov x0 ,0xabcd
bic x0,x0,#0xf      

位段操作指令

填充比特位bfi

提取比特位bfx

,Xn, #LSB, #WIDTH //get [0,width) from Xn,  to  [lsb,lsb+width) of Xd
 
  BFX Xd, Xn,#LSB, #WIDTH // get [lab,lsb+width) from Xn, to [x,width)
 
 //ubfx:fill '0' in other bits
 //sbuf:fill '1' when bit[lsb+width-1] is 1, or fill '0'      

测试程序:

.global my_bitfiled_test
my_bitfiled_test:
  mov x0,0xabcd
  bic x0,x0,0xf

  ldr x6, =0x346
  mov x1, 0
  bfi x1, x6, #8,#4

  ldr x2, =0x5678abcd
  ubfx x3, x2, #4, #8
  sbfx x4, x2, #4, #8

//read bitfiled from register
  mrs x7,ID_AA64ISAR0_EL1
  //support LSE?
  ubfx x8,x7, #20, #4
  //support AES?
  ubfx x9, x7, #4, #4      

运行结果如下:

零计数指令

mov x1, 0xf
clz x2, x1 //x2为60      

继续阅读