天天看點

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      

繼續閱讀