大量的 参考了: https://modexp.wordpress.com/2018/10/30/arm64-assembly/
// 1: BFI
指令 BFI
// 命令格式 BFI , , #, # 等价于 BFM 的 BFM , , #(- MOD 64), #(-1) BFI 指令的作用: Xn[0,width-1] 替换 Xd 寄存器中的 Xd[lsb,lsb width -1],Xd其他位置保持不变… // 举个例子: w0 结果为 0x12345678
mov w0, 0x5678 mov w1, 0x1234 bfi w0, w1, 16, 16
如果配额不确定,可以使用 gdb 单步调试下… 用途: 设置寄存器 a[7,4] 为5
val &=~(oxf << 4) val |=( 0x5 << 4) // bfi bfi x0,x1,#4,#4
在网上偷一张图…
UBFX
UBFX <Xd>, <Xn>, #<lsb>, #<width>
作用: Xn[lsb,lsb width-1],存储到 Xd 寄存器中… 与 SBFX 类似,但是 SBFX 会进行符号位扩展. 是根据 Bit[ lsb width-1 ]. 如果这个位置则所有高位为0,否则为0 1 .
mov X2,#0X8A ubfx x0,x2,#4,#4 sbfx x1,x2,#4,#4
x0 : (gdb) info r x0 x0 0x8 8 (gdb) // x1 符号位将进行 扩展. x1: gdb) info r x1 x1 0xfffffffffffffff8 -8
跳转指令
B | 跳转指令 b label |
---|---|
b.cond | 有条件的跳转 |
BL | BL label . 该指令将返回地址设置为 LR(x30),保存为 BL 当前指令 PC 4 . 也就是说,下一个指令的地址 |
BR | 跳转到 寄存器指定的地址: br Xn |
比较并跳转
CBZ | 比较和跳转 cbz Xt,label .寄存器 Xn 为0,跳到 label |
---|---|
CBNZ | cbnz Xt,label . 寄存器 Xn 不是0,跳转到 label |
TBZ | 测试位并跳转指令 TBZ R,#imm,label 判断 Rt 寄存器中的 第 imm 是0还是0,跳到0 label |
TBNZ | 测试位并跳转指令 TBZ R,#imm,label 判断 Rt 寄存器中的 第 imm 不是0,不是0,跳到0 label |
RET | 从子例程分支无条件返回寄存器中的地址,并提示这是子例程返回 |
System
MSR | 通用寄存器写入 AArch64 系统寄存器。 |
---|---|
MRS | 系统寄存器读取到通用寄存器中 |
SVC | 系统调用 |
NOP | 无操作”除了将程序计数器的值前置 4 之外,不执行任何操作。此指令可用于指令对齐目的。 |
有一个特殊用途的寄存器,允许您读取和写入名为NZCV的条件标志。
// read the condition flags
.equ OVERFLOW_FLAG, 1 << 28
.equ CARRY_FLAG, 1 << 29
.equ ZERO_FLAG, 1 << 30
.equ NEGATIVE_FLAG, 1 << 31
mrs x0, nzcv
// set the C flag
mov w0, CARRY_FLAG
msr nzcv, x0
msub
msub w1, w1, w22, w20 // w1 = w20-(w1*w22 )
MOVZ
MOVZ将立即数(16位值)移至寄存器,并且该立即数之外的所有其他位均设置为零。可以将立即数向左移0、16、32或48
MOVK
MOVK移动并立即取值,但保持寄存器的其他位不变
instruction value of x0
mov x0, #0x1f88 | 0x1f88
movk x0, #0xb7fb, lsl #16 | 0xb7fb1f88
movk x0, #0x7f, lsl #32 | 0x7fb7fb1f88
MOVN
MOVN通常用于移动位掩码,假设您要将位掩码0xffffffff0000ffff移至x0,然后将0xffff移至左侧16,这将使值变为0x00000000fffff0000,但是如果取反该值,它将变为0xffffffff0000ffff
instruction value of x0
MOVN x0, 0xFFFF, lsl 16 | 0xffffffff0000ffff
movn : 移动该值到指定的地方,然后取反…
neg
格式:NEG OPR执行的操作:(OPR)<-- —(OPR)亦即把操作数按位求反后末位加1,因而执行的操作也可表示为:(OPR)<-- 0FFFFH — (OPR) + 1NEG指令对标志的影响与用零作减法的SUB指令一样
.global ldr_test
ldr_test:
mov x0,xzr // 清 0
ldr w0,=0x12345678
neg w0,w0 // 按位求反后 . 0xedcba987 然后在加上1 ,所以为 w0,=0xedcba988
ret
mvn
mvn:与mov指令用法差不多,唯一的区别是:它赋值的时候,先按位取反 过程分析:先对4转换成2进制(00000100),取反(11111011),求其补码,因为是负数,所以先对其正数(01111011)求反(10000100),然后加一(10000101)=-5
负数的补码求法:对其正数求反+1
用这一特性,我们可以实现位 的反转
// bitwise NOT
ldr w0, =~0x12345678
mvn w0, w0
// w0 = 0x12345678 实现了位的反转...
adds
bit 64
ADDS <Xd>, <Xn|SP>, <R><m>{
, <extend> {
#<amount>}}
32-bit (sf == 0)
ADDS <Wd>, <Wn|WSP>, <Wm>{
, <extend> {
#<amount>}}
我们可以看下手册 这个是展示了 这个指令的实现.没有完全看懂。。 看到了这两句,首先就应该明白,这个是会改变 nzcv 标志的.
(result, nzcv) = AddWithCarry(operand1, operand2, ‘0’); PSTATE.<N,Z,C,V> = nzcv;
使用:
mov x1,0xffffffffffffffff
adds x0,x1,#2
mrs x2,nzcv
写道这里,突然想到,还是有必要 贴一下 NZCV
NZCV
Z, bit [30]
Zero condition flag. Set to 1 if the result of the last flag-setting instruction was zero, and to 0 otherwise. A result of zero often indicates an equal result from a comparison.
C, bit [29]
Carry condition flag. Set to 1 if the last flag-setting instruction resulted in a carry condition, for example an unsigned overflow on an addition.
V, bit [28]
Overflow condition flag. Set to 1 if the last flag-setting instruction resulted in an overflow condition, for example a signed overflow on an addition.
adc 指令
语法:
ADC Wd, Wn, Wm ; 32-bit
ADC Xd, Xn, Xm ; 64-bit
两数相加 并且加上 nzcv 中的 c 位. Rd = Rn + Rm + C,其中 R 为 W 或 X
adcs
语法:
与 adc 操作差不多。只是最后,会设置 nzcv .
ADCS Wd, Wn, Wm ; 32-bit
ADCS Xd, Xn, Xm ; 64-bit
//
Rd = Rn + Rm + C, where R is either W or X.
adcs 实现的伪代码
and
按位与 立即数举例:
AND Wd|WSP, Wn, #imm ; 32-bit
AND Xd|SP, Xn, #imm ; 64-bit
//
AND X0,X0,#0xF ; X0的值与0xF相位与后的值传送到X0
ands
与 and 操作方式一样,但是 这个会设置 nzcv
ANDS Wd, Wn, #imm ; 32-bit
ANDS Xd, Xn, #imm ; 64-bit
ccmn
CCMN Wn, #imm, #nzcv, cond ; 32-bit
CCMN Xn, #imm, #nzcv, cond ; 64-bit
// flags = if cond then compare(Rn, #-imm) else #nzcv, where R is either W or X.
cond 为真 ,比较 xn 与 -#imm . cond 为假,则取 nzcv
cmn
CMN Wn|WSP, #imm{, shift} ; 32-bit
CMN Xn|SP, #imm{, shift} ; 64-bit
//
将 xn + imm 的值相加,根据结果更新标志位,并且 丢弃结果.
mov w0,-1
cmn w0, 1 ; w0+1
beq failed
cmp
语法:
CMP Wn|WSP, Wm{, extend {#amount}} ; 32-bit CMP Xn|SP, Rm{, extend {#amount}} ; 64-bit 与 subs 是一样的实现 cmp w0,w1 w1-w0. 根据这个结果更新 nzcv ,但是并不保存结果.也不会改变 w0与 w1 的值
csel
CSEL Xd, Xn, Xm, cond ; 64-bit
// cond 为真 ,则 xd = xn. 否则 xd = xm
// r=(l > 64) ? 64 : l;
cmp x0, 64
csel x10, x0, x9, ls ; // x0 > 64 成立。 则 x10=x0 ,否则 x10=x9
CSET
该指令是 CSINC 的别名。
等效指令为 CSINC Wd, WZR, WZR, invert(cond)
CSET Xd, cond ; 64-bit
如果条件为 TRUE,则 Conditional Set 将目标寄存器设置为 1,否则将其设置为 0。
Rd = if cond then 1 else 0, where R is either W or X.
// Compare x0 with x0 and set x0 if equal. 设置 x0下为1
cmp x0, x0
cset x0, eq ;// x0 == x0 所以 eq 成立,则 x0 = 1
CSETM
条件设置掩码。
该指令是 CSINV 的别名。
等效指令是 CSINV Wd, WZR, WZR, invert(cond)。
CSETM Xd, cond ; 64-bit
用法:
如果条件为 TRUE,则条件设置掩码将目标寄存器的所有位设置为 1,否则
将所有位设置为 0。
Rd = if cond then -1 else 0,其中 R 是 W 或 X
// x0 = (x0 == x0) ? -1 : x0
cmp x0, x0
csetm x0, eq // x0 为 -1 . 所有位为1 . 0xffff.... . 计算机存储的为补码。0xfff... 这个值就是为 -1
CSINC
Conditional Select Increment.
This instruction is used by the aliases:
• CINC.
• CSET
语法:
CSINC Xd, Xn, Xm, cond ; 64-bit
// cond 为真,返回 xd=xn,否则 xd = Xm+1
Rd = if cond then Rn else (Rm + 1), where R is either W or X
CSINV
有条件的选择反转。
该指令由别名使用:
• CINV。
• CSETM
语法
CSINV Xd, Xn, Xm, cond ; 64-bit
// cond 为真, xd = Xn 否则 Xd = NOT(Xm)就是按位取反.
Rd = if cond then Rn else NOT (Rm),其中 R 为 W 或 X。
CSNEG
条件选择否定。
该指令由别名 CNEG 使用
语法:
CSNEG Xd, Xn, Xm, cond ; 64-bit
// cond 为真 Xd=Xn 否则 Xd = -Xm ( - 就是取反,就是负值
Rd = if cond then Rn else -Rm,其中 R 是 W 或 X
EON
按位异或非
EON Xd, Xn, Xm{
, shift #amount} ; 64-bit
// Xd = ~(Xn^Xm) 。 就是 整体取反,然后Xn与 Xm 进行异或
Rd = Rn EOR NOT shift(Rm, amount), where R is either W or X.
// for example
// x0 = ~(x0 ^ x0) ,最后这个 x0的值为 -1
eon x0, x0, x0
EOR
按位异或
立即数的形式
EOR Xd|SP, Xn, #imm ; 64-bit
操作:
Rd = Rn EOR imm, where R is either W or X.
// for example
/ Exclusive-OR the register with itself.
eor x0, x0, x0
补充下异或
异或运算的作用
参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。
异或真值表:
0^0 = 0, 1^0 = 1,0^1 = 1,1^1 = 0
ERET
从异常中返回。 它根据 SPSR_ELn 恢复处理器状态并分支到
ELR_ELn,其中 n 是当前异常级别。
这个跳过....
LSL
逻辑左移(寄存器)。
该指令是 LSLV 的别名。
等效指令是 LSLV Wd、Wn、Wm。
LSL Xd, Xn, Xm ; 64-bit
Rd = LSL(Rn, Rm), where R is either W or X.
逻辑左移与算术左移的操作是一样的,都是将操作数向左移位,低位补零,移除的高位进行丢弃。
// 用 arm32 来演示,这个与 arm64 是一样的,没有什么区别
MOV R0, #5
MOV R1, R0, LSL #2
上述命令,就是将5存储到R0寄存器上(R0 = 5), 然后将R0逻辑左移2位后传送到R1寄存器中。
十进制5的二进制数值是0101,进行逻辑左移2位就是0001_0100, 也就是十进制中的20。其实每逻辑左移1位就相当于原数值进行乘2操作,5逻辑左移2位其实就是5 x 2^2 = 20。下方是该操作的原理图
LSLV
逻辑左移变量。
该指令由别名 LSL(寄存器)使用。
LSLV Xd, Xn, Xm ; 64-bit
// 与 lsl 效果一样的
Rd = LSL(Rn, Rm), where R is either W or X.
LSR
逻辑右移
This instruction is an alias of LSRV.
The equivalent instruction is LSRV Wd, Wn, Wm
用法:
LSR Xd, Xn, Xm ; 64-bit
Rd = LSR(Rn, Rm), where R is either W or X.
逻辑右移与逻辑左移是相对的,逻辑右移其实就是往右移位,左边补零
LSRV
和 LSR 一样
MADD
乘加。
该指令由别名 MUL 使用
MADD Xd, Xn, Xm, Xa ; 64-bit
// 第三个寄存器的值加上 第一和第二个寄存器的 乘积.
Rd = Ra + Rn * Rm, where R is either W or X.
MNEG
乘负。
该指令是 MSUB 的别名。
等效指令为 MSUB Wd, Wn, Wm, WZR
MNEG Xd, Xn, Xm ; 64-bit
// 两个寄存器 相乘,然后取反..
Rd = -(Rn * Rm), where R is either W or X.
MSUB
乘减法。
该指令由别名 MNEG 使用。
MSUB Xd, Xn, Xm, Xa ; 64-bit
// 操作
Rd = Ra - Rn * Rm, where R is either W or X.
MUL
乘。
该指令是 MADD 的别名。
等效指令为 MADD Wd、Wn、Wm、WZR。
MUL Xd, Xn, Xm ; 64-bit
操作:
Rd = Rn * Rm, where R is either W or X.
MVN
按位非。 该指令是 ORN(
移位寄存器)的别名。 等效指令是 ORN Wd, WZR, Wm{ , shift #amount}。 MVN Xd, Xm{ , shift #amount} ; 64-bit 操作: 将寄存器值的按位反转写入目标寄存器。 Rd = NOT shift(Rm, amount), where R is either W or X. // copy the zero register inverted mvn x0, xzr ; // x0 等于 -1
NEG
shifted register :举例
取反(移位寄存器)。
该指令是 SUB(移位寄存器)的别名。
等效指令为 SUB Wd, WZR, Wm {
, shift #amount}
NEG Xd, Xm{
, shift #amount} ; 64-bit
取反一个可选移位的寄存器值,并将结果写入
目的地寄存器
Rd = 0 - shift(Rm, amount), where R is either W or X.
NEGS
否定,设置标志。
该指令是 SUBS(移位寄存器)的别名。
等效指令为 SUBS Wd, WZR, Wm {
, shift #amount}
NEGS Xd, Xm{
, shift #amount} ; 64-bit
取反可选移位的寄存器值,并将结果写入目标
登记。 它根据结果更新条件标志.与上面的 NEG 比较的话,多了一步,设置 NZCV
Rd = 0 - shift(Rm, amount), where R is either W or X.
看下 伪代码,确实看到了 会设置 nzcv 。。
NGC
用进位取反。
该指令是 SBC 的别名。
等效指令为 SBC Wd、WZR、Wm。
NGC Xd, Xm ; 64-bit
# 不知道 为啥要减1 ??? 没看懂
Rd = 0 - Rm - 1 + C, where R is either W or X.
NGCS
与上面的 NGC 操作一样,只是最后会根据结果 更新 NZCV
NOP
空指令 用法 No Operation 除了将程序计数器的值加 4 之外什么都不做。这条指令 可用于指令对齐目的。 笔记 不能保证在程序中包含 NOP 指令的时序效果。 它可以增加 执行时间,保持不变,甚至减少它。 因此,NOP 指令不适用于 定时循环。
ORN
按位 OR NOT(移位寄存器)。
该指令由别名 MVN 使用。
ORN Xd, Xn, Xm{
, shift #amount} ; 64-bit
// Rn 或上一个 ( 取反的 Xm)
Rd = Rn OR NOT shift(Rm, amount), where R is either W or X.
// x0 = (x0 | ~xzr)
orn x0, x0, xzr
ORR
按位或(立即数)。
该指令由别名 MOV(位掩码立即数)使用
ORR Xd|SP, Xn, #imm ; 64-bit
Rd = Rn OR imm, where R is either W or X.
// for example
orr w6, w2, w4 // w6 = w2 | w4
RET
从子程序返回。
句法
RET {
Xn}
在哪里:
Xn
是保存要跳转到的地址的通用寄存器的 64 位名称。
如果不存在,则默认为 X30。
用法
从子程序分支无条件返回到寄存器中的地址,并提示这是一个
子程序返回。
一般是在函数的结尾直接写
ret
ROR
循环右移操作
ROR Xd, Xs, #shift ; 64-bit
提供一个寄存器内容的值
位。 从右端旋转出来的位被插入到左边空出的位位置
Rd = ROR(Rs, shift), where R is either W or X.
SBC
带进位减法。
此指令由别名 NGC 使用
语法:
SBC Xd, Xn, Xm ; 64-bit
计算过程: 对第二个操作数取反,然后把第一个操作数,第二个操作数相加,这个过程会影响到 PSTATE寄存器的 C 标志位,最后把c 标志位也加上.
所以应该: Xd = Xn + NOT(Xm) +C
这个好像与下面的手册写的不太一样..
这是怎么回事呢???0
Rd = Rn - Rm - 1 + C, where R is either W or X.
// 举个例子
mov x1,#3
mov x2,#1
sbc x0,x1,x2
mrs x3,nzcv
最后 x0 = 2
// 如果按照 第二种计算方法
Rd = Rn - Rm - 1 + C, where R is either W or X.
// 没有进位 c 为 1.
3-1-1+C =1+1 = 2
测试一下 执行玩 mrs x3,nzcv 此时的 x3=600… 此时 : z/c 为1 执行完后, nzcv 不变。 还是 6000…
SBCS
与上面的 sbc 操作一样,但这个会根据结果更新 nzcv
SBFIZ
有符号位域插入零。
该指令是 SBFM 的别名。
等效指令为 SBFM Wd, Wn, #(-lsb MOD 32), #(width-1)
SBFIZ Xd, Xn, #lsb, #width ; 64-bit
### 没看懂 ...
SBFM
签名位域移动。 该指令由别名使用: • ASR(立即)。 • SBFIZ。 • SBFX。 • SXTB。 • SXTH。 • SXTW。 后续来补充
SBFX
后面来补充
SDIV
除法
SDIV Xd, Xn, Xm ; 64-bit
有符号除法将一个有符号整数寄存器值除以另一个有符号整数寄存器值,并写入
结果到目标寄存器。 条件标志不受影响
Rd = Rn / Rm, where R is either W or X.
SEV
跳过
SUB
减法
SUB Xd|SP, Xn|SP, Rm{
, extend {
#amount}} ; 64-bit
Rd = Rn - LSL(extend(Rm), amount), where R is either W or X.
SUBS
extended register 举例:
减法(扩展寄存器),设置标志。
该指令由别名 CMP(扩展寄存器)使用
会更新标志位的.
SUBS Xd, Xn|SP, Rm{
, extend {
#amount}} ; 64-bit
SVC
主管调用以允许应用程序代码调用操作系统。 它生成一个异常定位异常
1级(EL1)
SVC #imm
SXTB
有符号扩展字节。
该指令是 SBFM 的别名。
等效指令为 SBFM Wd、Wn、#0、#7。
有符号扩展字节从寄存器中提取一个 8 位值,将其符号扩展为寄存器的大小,然后
将结果写入目标寄存器
SXTB Xd, Wn ; 64-bit
符号扩展顾名思义就是将字节或者将半字的最高符号位进行扩展,最后都扩展到指定的位数
// 举个例子
mov w0, 255
sxtb x0, w0 // w0 = 255.=ff . 根据最高位的bit ,为1 .所以 32-63 bit 都为1 .
SXTH
符号扩展半字。
该指令是 SBFM 的别名。
等效指令为 SBFM Wd、Wn、#0、#15。
SXTH Xd, Wn ; 64-bit
用法:符号扩展半字提取一个 16 位值,将其符号扩展为寄存器的大小,然后写入
结果到目标寄存器。
根据 16位的值,来扩展高位的值.
Rd = SignExtend(Wn<15:0>), where R is either W or X.
SXTW
符号扩展字。
该指令是 SBFM 的别名。
等效指令为 SBFM Xd, Xn, #0, #31
根据 31 位值的内容进行扩展...
Xd = SignExtend(Wn<31:0>).
TBNZ
测试位不为0,则跳转
语法:
TBNZ R<t>, #imm, label
举例:
tbnz w24, #0x6, 0x19307005c ; w24第6位,若不为0,则跳转到0x19307005c执行
这不是子程序调用或返回。 该指令不影响条件标志。
TBZ
测试位为0,跳转
TBZ R<t>, #imm, label
这不是子例程调用或返回。 该指令不影响条件标志。
tbz w24, #0x6, 0x19307005c ; 即w24第6位,若为0,则跳转到0x19307005c执行
TST
immediate 举例:
设置条件标志并丢弃结果。
该指令是 ANDS(立即数)的别名。
等效指令为 ANDS WZR、Wn、#imm。
TST Xn, #imm ; 64-bit
操作:
Rn AND imm, where R is either W or X.
TST指令将操作数1与操作数2做逻辑与运算,和ANDS的区别就是不保存结果。TST会改变CPSR的条件标志位
for example
tst r0,#0x1
beq tst_pass
UBFIZ
无符号位域插入零。
该指令是 UBFM 的别名。
等效指令是 UBFM Wd, Wn, #(-lsb MOD 32), #(width-1)。
UBFIZ Xd, Xn, #lsb, #width ; 64-bit
提前 Xn的 Bit[0,width-1],存储到 Xd[lsb,lsb+width-1] 寄存器中.
其他位填充0 ..
/ If x1 is 0x12345678, 0x00007800 is placed in x0.
ubfiz x0, x1, 8, 8
假设 x1 : 0x12345678 ubfiz x0, x1, 3, 9
如下图所示: 最后 x0 = 0x3c0
UBFM
Unsigned Bitfield Move.
This instruction is used by the aliases:
• LSL (immediate).
• LSR (immediate).
• UBFIZ.
• UBFX.
• UXTB.
• UXTH
语法:
UBFM Xd, Xn, #<immr>, #<imms> ; 64-bit
这个 和 UBFIZ 是一样的.
UBFX
无符号位域提取。
该指令是 UBFM 的别名。
等效指令是 UBFM Wd, Wn, #lsb, #(lsb+width-1)。
UBFX Xd, Xn, #lsb, #width ; 64-bit
UBFX 指令的作用是:
Xn[lsb,lsb+width-1] 存储到 Xd 寄存器中.其他位保持不变,不做符号位扩展.
mov x2,#0x8a ubfx x0,x2,#4,#4 效果图
UDIV
无符号除法。
UDIV Xd, Xn, Xm ; 64-bit
Rd = Rn / Rm, where R is either W or X.
将一个无符号整数寄存器值除以另一个无符号整数寄存器值,
并将结果写入目标寄存器。 条件标志不受影响
UXTB
无符号扩展字节。
该指令是 UBFM 的别名。
等效指令为 UBFM Wd、Wn、#0、#7。
UXTB Wd, Wn
无符号扩展字节从寄存器中提取一个 8 位值,将其零扩展为寄存器的大小,
并将结果写入目标寄存器。
Wd = ZeroExtend(Wn<7:0>)
应该就是 Wd = Wn . 其他位用0补充...
UXTH
与 UXTB 原理一样,只是这个是 半字.
stur
STUR Xt, [Xn|SP{
, #simm}] ; 64-bit
用法:
stur 后面的地址为 负数 。
stur w12, [x29, #-0x18]
w12 的内容 存储在 x29-0x18 的地址里面去.
STURB
与 stur 操作方式相同,只是这个 一次操作 一个 Byte(8bit)
STURH
与 stur 操作方式相同,只是这个 一次操作 一个 半字
STXP
存储独占寄存器对。
LDUR
Load Register
LDUR Xt, [Xn|SP{
, #simm}] ; 64-bit
跟ldr一样,只不过,ldur通常后面的立即数是负数
举例:
ldur x1,[x0,#-1] ;//通常ldur 用来负数运算 代表x0-1 地址的内容 赋值给 x1
LDURB
Load Register Byte LDURB Wt, [Xn|SP{, #simm}] 与 ldur 一样,只是这个装载的是 Byte
LDURH
Load Register Halfword LDURH Wt, [Xn|SP{, #simm}] 装载的是 半字
LDURSB
Load Register Signed Byte LDURSB Xt, [Xn|SP{, #simm}] ; 64-bit 装载一个有符号的字节
LDRSH
加载寄存器有符号半字
Syntax
LDRSH Wt, [Xn|SP], #simm ; 32-bit, Post-index
LDRSH Xt, [Xn|SP], #simm ; 64-bit, Post-index
LDRSH Wt, [Xn|SP, #simm]! ; 32-bit, Pre-index
LDRSH Xt, [Xn|SP, #simm]! ; 64-bit, Pre-index
LDRSH Wt, [Xn|SP{
, #pimm}] ; 32-bit
LDRSH Xt, [Xn|SP{
, #pimm}] ; 64-bit
加载寄存器有符号半字(立即)从内存中加载一个半字,将其符号扩展为 32 位或
64 位,并将结果写入寄存器
RSB
RSB 应该是 32位的指令…
没有进位的反向减法。
RSB{
S}{
cond} {
Rd}, Rn, Operand2
RSB r4, r4, #1280 ; 从 1280 中减去 R4 的内容