- 加法指令ADD、ADDS、ADCS
- 减法指令SUB、SUBS、SBC,SBCS,CMP
- 位操作AND, ANDS, ORR、EOR、BFI、UBFX、SBFX
1.1 ADD
a = a + b, 没有进位标志,也不会利用进位标志
- ADD (extended register) :
- Define:
ADD
, , , { {#}} - Example1:
add x0, x1, x2
( x0 = x1 + x2 ) - Example2:
add x0, x1, x2, lsl #5
( x0 = x1 + (x2 << 5) )
- Define:
- ADD (immediate):
- Define:
ADD
, note shift supports #0 and #12 only., , # {, lsl <#shift>} - Example1:
add x1, x2, #8
(x1 = x2 + 8) - Example2:
add x1, x2, #8, lsl #12
( x1 = x2 + (8 << 12) )
- Define:
- ADD (shifted register):
- Define:
ADD
, note #amount range 0 to 63, , {,#} - Note: LSL when shift = 0, LSR when shift = 1, ASR when shift = 2
- Example1:
add x1, x2, x3, asr #2
- Define:
(a,C) = a + b, 带进位标志的加法,用法和ADD一样
1.3 ADCS
(a,C) = a + b + C,带进位标志的加法,且需要加上C标志位,用法和ADD一样。 注意,如果加法溢出的时候C标志位会置位为1,比如,a = 0xFFFFFFFFFFFFFFFF, b = 1,此时,加法溢出,C置位1。
1.4 ADR
a = b + PC, 当前程序的PC值加上给定的地址偏移
- ADR
- Define:
ADR
, - Note, no 32-bit
- Note,
- Example01:
adr x1, #25
- Define:
方法1:使用MSR/MRS指令
msr NZCV, xzr// clear the NZCV
mrs x0, NZCV// 查看NZCV寄存器,NZCV在高位28 - 32 bits
方法2:使用ADCS的+C特性
adcs x0, zxr, xzr
让两个0寄存器相加 0+0+c就可以得到C标志位的值2. 减法指令 减法指令包含SBC,SBCS。请参考ARMv8手册,C6.2.231 C6-1299
2.1 SUB
a = a - b, 没有进位标志,也不会利用进位标志。使用方法和ADD一致。
2.2 SUBS
(a,N) = a - b, 会置标志位N。使用方法和SUBS一致,减成负数的时候,其余位置补1。
2.3 SBC
a = a - b - 1 + C
- SBC (Subtract with Carry):
- Define:
SBC
, , - Example:
sbc x0, xzr, xzr
- Define:
(a, N) = a - b - 1 + C, 如果减出负数的话,N会被置位
- SBC (Subtract with Carry, setting N flag):
- Define:
SBCS
, , - Example:
sbcs x0, xzr, x1
- Define:
比较指令,实际上也使用SBC实现的, cmp x1, x2
- 若x1 > x2, NCZV = 0100
- 若x1 = x2, NCZV = 0110
- 若x1 < x2, NCZV = 1000
CMP , {, {#}}
Define 2:
CMP , #{, }
Define 3:
CMP , {,#}
Example:
* The function cmp_and_return_test:
* if a >= b return 1
* if a < b return 0
test_cmp:
cmp x0, x1// if x0 >= x1,C is 1;
if x0 < x1 C is 0
adcs x0, xzr, xzr // 0 + 0 + C
3. 位操作 位操作包含AND, ANDS, ORR、EOR、BFI、UBFX、SBFX, 分别是与、与置位标志位、或、异或、插入、无符号提取、有符号提取。
3.1 ORR
a = a | b;
Define 1:
ORR , , #
Define 2:
ORR , , {,#}
test_orr:
// ORR test0xAA oor 0x55 = 0xFF
//0xFF oor 0x00 = 0xFF
//0xFF oor 0xFF = 0xFF
//0x00 oor 0x00 = 0x00
mov x0, xzr
mov x1, #0xAA
mov x2, #0x55
orr x1, x1, x2mov x1, #0xFF
orr x1, x1, xzrmov x1, #0xFF
orr x1, x1, x1orr x1, xzr, xzrrettest_ubfx:
// x1: 0000 0000 0000 0000->0000 0000 0000 1111
//^
//|
// x2:0000 0000 1111 0000
mov x1, xzr
mov x2, #0x00F0
ubfx x1, x2, #0x4, #0x4// x1: 0000 0000 0000 0000->1111 1111 1111 1111
//^
//|
//1000 0000 1111 0000
mov x1, xzr
mov x2, #0x80F0
3.2 EOR
a = a ^ b;
Define 1:
EOR , , #
Define 2:
EOR , , {,#}
test_eor:
// test 2 exchange the value x1 = 0x07, x2 = 0xAA
// using the orr, just use two register.
// x1 = x1^x2
// x2 = x2^x1
// x1 = x1^x2
ldr x1, =0x07
ldr x2, =0xAA
eor x1, x1, x2
eor x2, x2, x1
eor x1, x1, x2
ret
几个EOR的小技巧:
- 翻转某些位: 比如把右数第0位到第3位翻转: 1010 1001 ^ 0000 1111 = 1010 0110
- 交换数值: a=a^b; b=b^a; a=a^b,不借助第三个变量
- 置0: a^a
- 判断相等 a^b == 0
3.3.1 AND a = a & b;
Define 1:
AND , , #
Define 2:
AND , , {,#}
msr NZCV, xzr// clear the NZCV
ldr x1, =0xAA
ldr x2, =0x0
// test AND, no Z flag. x1 = x1&x2
and x1, x1, x2
mrs x0, NZCV
3.3.2 ANDS (a, z) = a & b. 如果a和b与的结果为0,z flag置位
// test ANDS, z flag, if the result is 0, Z is 1
msr NZCV, xzr// clear the NZCV
mov x0, xzr
ldr x1, =0xAA
ands x1, x1, x2
mrs x0, NZCV
3.4 BFI
Define 1:
BFI , , #, #
从Xn寄存器里面从低位开始,插入到Xd寄存器从#
读取Xn寄存器的低位开始计算,插入到Xd寄存器从#
test_bfi:
// 0000 0000 0000 1010
//|
//V
//0000 0000 0000 0000->0000 1010 0000 0000
ldr x1, =0x000A
mov x2, xzr
bfi x2, x1, #0x8, #0x4// 0000 0000 0000 1010
//|
//V
//0000 0101 0000 0000->0000 1010 0000 0000
ldr x1, =0x000A
mov x2, #0x0500
bfi x2, x1, #0x8, #0x4ret
3.5 UBFX/SBFX
Define:
UBFX , , #, #
Define:
SBFX , , #, #
读取Xn寄存器的#
// x1:0000 0000 1111 0000
//|
//V
// x2: 0000 0000 0000 0000->0000 0000 0000 1111mov x1, #0x00F0
mov x2, xzr
ubfx x2, x1, #0x4, #0x4//1000 0000 1111 0000
//|
//V
// x1: 0000 0000 0000 0000->1111 1111 1111 1111
mov x1, #0x80F0
mov x2, xzr
sbfx x2, x1, #0x4, #0x4
文章图片
Ref [1] Arm Armv8-A Architecture Registers-NZCV, Condition Flags
[2] ARM Cortex-A Series Programmer's Guide for ARMv8-A - Arithmetic and logical operations
[2] ARM架构(三)ARMv8 Programm Model Overview
【04_ARMv8指令集-运算指令集】[3] [ARMv8官方手册学习笔记(三):寄存器](