做人呢,最紧要就系开心啦

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

498次阅读
一条评论

条件操作码

在 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 = Xn + Xm + c 

SBC 指令

SBC Xd, Xn, Xm //Xd = Xn-Xm-1+C

CMP 指令

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

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

当 x1>=x2,C=1
x1<x2, C=0

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

 .global my_add_test
  my_add_test:
    mov x0,#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 x1, x2
    adc x4, xzr, xzr 
    ret 

执行结果如下:
ARM64 基础 6:A64 的算术和移位指令

练习 2:cmp 和 sbc 搭配使用


/*
 * when arg1 >= 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 x0, x1
    sbc x0, xzr, xzr  //0-0-1+C

    ret

移位指令

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

按位与操作

AND Xd,Xn  -->Xd = Xd & Xn
ANDS 影响 Z 标志位

ands 影响 z 比特位

/*
 * ands influence Z flag in pstate
 */
.global my_ands_test
my_ands_test:
    mov x1, #0x3
    mov x2, #0
    ands x3,x1,x2

    mrs x0, nzcv  //z at 30bit
    ret

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

按位或 / 异或

ORR Xd, Xn  -->Xd = Xd | Xn
EOR Xd, Xn  -->Xd = Xd ^ Xn

异或的三个特点:

(1)0 异或任何数 = 任何数;
(2)1 异或任何数 = 任何数相反数;
(3)任何数异或自己 =0;

异或的几个技巧运用

(1) 使某些位翻转:

0xffff,ffff ^ 0x1<<5  // 把第 5 位翻转

(2) 交换两个数

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

(3) 在汇编里设置 0

eor x0,x0

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

return ((a^b)==0)

按位清除

bic: 位清零指令

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

位段操作指令

填充比特位 bfi

提取比特位 bfx


  BFI Xd,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

    ret

运行结果如下:
ARM64 基础 6:A64 的算术和移位指令

零计数指令

clz, 计算最高位 1 前的 0 个数

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

正文完
 
admin
版权声明:本站原创文章,由 admin 2021-11-02发表,共计1754字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(一条评论)