记录一些 arm64指令的用法

大量的 参考了:
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有条件的跳转
BLBL label . 该指令将返回的地址设置到 LR(x30),保存的为 BL 指令的当前的 PC+4 . 也就是下一条指令的地址
BR跳转到 寄存器指定的地址: br Xn

比较并跳转

CBZ比较并且跳转 cbz Xt,label .寄存器 Xn 为0,跳到 label
CBNZcbnz Xt,label . 寄存器 Xn 不为0,则跳转到 label
TBZ测试位并跳转指令 TBZ R,#imm,label 判断 Rt 寄存器中的 第 imm 位是否为0,为0,则跳到 label
TBNZ测试位并跳转指令 TBZ R,#imm,label 判断 Rt 寄存器中的 第 imm 位是否不为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 
    

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 = 10^1 = 11^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 的内容

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要进行ARM指令验证,可以按照以下步骤进行: 1. 确定验证目标:首先,确定要验证的ARM指令集和目标硬件平台。ARM有多个指令集架构(如ARMv7、ARMv8等),而不同的硬件平台可能有不同的配置和特性。 2. 编写测试程序:根据验证目标,编写测试程序来执行所需的ARM指令。测试程序可以使用汇编语言(如ARM汇编)或高级语言(如C/C++)编写。 3. 选择验证方法:根据验证目标和测试程序,选择适当的验证方法。常见的验证方法包括仿真验证、硬件验证和实际运行验证。 - 仿真验证:使用ARM仿真器(如QEMU)或模拟器进行指令验证。这种方法可以在不实际运行硬件的情况下进行快速验证,但可能无法完全模拟硬件的行为。 - 硬件验证:将测试程序加载到目标硬件平台上进行验证。这种方法更接近实际运行环境,但可能需要额外的硬件设备和资源。 - 实际运行验证:在实际应用中运行测试程序,以验证指令的正确性和性能。这种方法最接近实际使用情况,但可能需要更多的时间和资源。 4. 运行验证:根据选择的验证方法,运行测试程序进行验证。记录和分析验证结果,确保ARM指令的正确性和预期行为。 5. 调试和优化:如果验证结果不符合预期,需要进行调试和优化。可以使用调试工具(如GDB)来跟踪和分析程序执行过程,以找出问题所在并进行修复。 6. 重复验证:对于复杂的ARM指令或涉及多个测试场景的情况,可能需要多次运行验证步骤,直到满足所有要求。 请注意,在进行ARM指令验证时,确保遵循ARM架构手册提供的规范和指导,以确保正确性和稳定性。此外,确保在适当的环境下进行验证,并根据实际需求进行必要的测试覆盖和性能评估。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值