We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
加法指令有ADD、ADDS、ADCS。 ADD一般性加法指令,ADCS带C标志位运算的加法指令,ADDS影响C标志位的加法运算。
a = a + b, 没有进位标志,也不会利用进位标志
ADD <Xd|SP>, <Xn|SP>, <Wm>, {<extend> {#<amount>}}
add x0, x1, x2
add x0, x1, x2, lsl #5
ADD <Xd|SP>, <Xn|SP>, #<imm>{, lsl <#shift>}
add x1, x2, #8
add x1, x2, #8, lsl #12
ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
add x1, x2, x3, asr #2
(a,C) = a + b, 带进位标志的加法,用法和ADD一样
(a,C) = a + b + C,带进位标志的加法,且需要加上C标志位,用法和ADD一样。 注意,如果加法溢出的时候C标志位会置位为1,比如,a = 0xFFFFFFFFFFFFFFFF, b = 1,此时,加法溢出,C置位1。
a = b + PC, 当前程序的PC值加上给定的地址偏移
ADR <Xd>, <label>
adr x1, #25
msr NZCV, xzr // clear the NZCV mrs x0, NZCV // 查看NZCV寄存器,NZCV在高位28 - 32 bits
adcs x0, zxr, xzr 让两个0寄存器相加 0+0+c就可以得到C标志位的值
adcs x0, zxr, xzr
减法指令包含SBC,SBCS。请参考ARMv8手册,C6.2.231 C6-1299
a = a - b, 没有进位标志,也不会利用进位标志。使用方法和ADD一致。
(a,N) = a - b, 会置标志位N。使用方法和SUBS一致,减成负数的时候,其余位置补1。
a = a - b - 1 + C
SBC <Xd>, <Xn>, <Xm>
sbc x0, xzr, xzr
(a, N) = a - b - 1 + C, 如果减出负数的话,N会被置位
SBCS <Xd>, <Xn>, <Xm>
sbcs x0, xzr, x1
比较指令,实际上也使用SBC实现的, cmp x1, x2
Define 1: CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}
CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}
Define 2: CMP <Xn|SP>, #<imm>{, <shift>}
CMP <Xn|SP>, #<imm>{, <shift>}
Define 3: CMP <Xn|SP>, <Xm>{, <shift> #<amount>}
CMP <Xn|SP>, <Xm>{, <shift> #<amount>}
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
位操作包含AND, ANDS, ORR、EOR、BFI、UBFX、SBFX, 分别是与、与置位标志位、或、异或、插入、无符号提取、有符号提取。
a = a | b;
Define 1: ORR <Xd|SP>, <Xn>, #<imm>
ORR <Xd|SP>, <Xn>, #<imm>
Define 2: ORR <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
ORR <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
test_orr: // ORR test 0xAA 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, x2 mov x1, #0xFF orr x1, x1, xzr mov x1, #0xFF orr x1, x1, x1 orr x1, xzr, xzr ret test_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
a = a ^ b;
Define 1: EOR <Xd|SP>, <Xn>, #<imm>
EOR <Xd|SP>, <Xn>, #<imm>
Define 2: EOR <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
EOR <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
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的小技巧:
a = a & b;
Define 1: AND <Xd|SP>, <Xn>, #<imm>
AND <Xd|SP>, <Xn>, #<imm>
Define 2: AND <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
AND <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
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
(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
Define 1: BFI <Xd>, <Xn>, #<lsb>, #<width>
BFI <Xd>, <Xn>, #<lsb>, #<width>
从Xn寄存器里面从低位开始,插入到Xd寄存器从#开始,#长度。
读取Xn寄存器的低位开始计算,插入到Xd寄存器从#开始,#长度。这个没有办法控制Xd的位置,只能从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, #0x4 ret
Define: UBFX <Xd>, <Xn>, #<lsb>, #<width>
UBFX <Xd>, <Xn>, #<lsb>, #<width>
Define: SBFX <Xd>, <Xn>, #<lsb>, #<width>
SBFX <Xd>, <Xn>, #<lsb>, #<width>
读取Xn寄存器的#开始,#长度开始计算,替换到Xd寄存器低位的位置#长度。这个没有办法控制Xd的位置,只能从Xd的最低位开始。 SBFX是有符号的,替换之后Xd 其他位0变为1。
// x1: 0000 0000 1111 0000 // | // V // x2: 0000 0000 0000 0000 -> 0000 0000 0000 1111 mov 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
[1] Arm Armv8-A Architecture Registers-NZCV, Condition Flags
[2] ARM Cortex-A Series Programmer's Guide for ARMv8-A - Arithmetic and logical operations
[3] ARM架构(三)ARMv8 Programm Model Overview
[4] ARMv8官方手册学习笔记(三):寄存器
The text was updated successfully, but these errors were encountered:
No branches or pull requests
04_ARMv8指令集-运算指令集
1. 加法指令
加法指令有ADD、ADDS、ADCS。 ADD一般性加法指令,ADCS带C标志位运算的加法指令,ADDS影响C标志位的加法运算。
1.1 ADD
a = a + b, 没有进位标志,也不会利用进位标志
ADD <Xd|SP>, <Xn|SP>, <Wm>, {<extend> {#<amount>}}
add x0, x1, x2
( x0 = x1 + x2 )add x0, x1, x2, lsl #5
( x0 = x1 + (x2 << 5) )ADD <Xd|SP>, <Xn|SP>, #<imm>{, lsl <#shift>}
, note shift supports #0 and 06_ARMv8_指令集_一些重要的指令 #12 only.add x1, x2, #8
(x1 = x2 + 8)add x1, x2, #8, lsl #12
( x1 = x2 + (8 << 12) )ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
, note #amount range 0 to 63add x1, x2, x3, asr #2
1.2 ADDS
(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 <Xd>, <label>
adr x1, #25
1.5 关于查看C flag的方法
方法1:使用MSR/MRS指令
方法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 <Xd>, <Xn>, <Xm>
sbc x0, xzr, xzr
2.4 SBCS
(a, N) = a - b - 1 + C, 如果减出负数的话,N会被置位
SBCS <Xd>, <Xn>, <Xm>
sbcs x0, xzr, x1
2.5 CMP
比较指令,实际上也使用SBC实现的, cmp x1, x2
Define 1:
CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}
Define 2:
CMP <Xn|SP>, #<imm>{, <shift>}
Define 3:
CMP <Xn|SP>, <Xm>{, <shift> #<amount>}
Example:
** The function cmp_and_return_test:*
** if a >= b return 1*
** if a < b return 0*
3. 位操作
位操作包含AND, ANDS, ORR、EOR、BFI、UBFX、SBFX, 分别是与、与置位标志位、或、异或、插入、无符号提取、有符号提取。
3.1 ORR
a = a | b;
Define 1:
ORR <Xd|SP>, <Xn>, #<imm>
Define 2:
ORR <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
3.2 EOR
a = a ^ b;
Define 1:
EOR <Xd|SP>, <Xn>, #<imm>
Define 2:
EOR <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
几个EOR的小技巧:
3.3 AND
3.3.1 AND
a = a & b;
Define 1:
AND <Xd|SP>, <Xn>, #<imm>
Define 2:
AND <Xd|SP>, <Xn>, <Xm>{, <shift> #<amount>}
3.3.2 ANDS
(a, z) = a & b. 如果a和b与的结果为0,z flag置位
3.4 BFI
Define 1:
BFI <Xd>, <Xn>, #<lsb>, #<width>
从Xn寄存器里面从低位开始,插入到Xd寄存器从#开始,#长度。
读取Xn寄存器的低位开始计算,插入到Xd寄存器从#开始,#长度。这个没有办法控制Xd的位置,只能从Xd的最低位开始。
3.5 UBFX/SBFX
Define:
UBFX <Xd>, <Xn>, #<lsb>, #<width>
Define:
SBFX <Xd>, <Xn>, #<lsb>, #<width>
读取Xn寄存器的#开始,#长度开始计算,替换到Xd寄存器低位的位置#长度。这个没有办法控制Xd的位置,只能从Xd的最低位开始。 SBFX是有符号的,替换之后Xd 其他位0变为1。
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
[3] ARM架构(三)ARMv8 Programm Model Overview
[4] ARMv8官方手册学习笔记(三):寄存器
The text was updated successfully, but these errors were encountered: