当前位置:   article > 正文

ARM 汇编指令_arm ldp

arm ldp

mov 复制

mov: 将某一寄存器的值复制到另一寄存器(只能用于寄存器与寄存器或者寄存器与常量之间传值,不能用于内存地址),如:

mov x1, x0        ; 将寄存器 x0 的值复制到寄存器 x1 中 

add 加

add: 将某一寄存器的值和另一寄存器的值 相加 并将结果保存在另一寄存器中,如:

add x0, x0, #1    ; 将寄存器 x0 的值和常量 1 相加后保存在寄存器 x0 中 
add x0, x1, x2    ; 将寄存器 x1 和 x2 的值相加后保存到寄存器 x0 中 
add x0, x1, [x2]  ; 将寄存器 x1 的值加上寄存器 x2 的值作为地址,再取该内存地址的内容放入寄存器 x0 中 

sub 减

sub: 将某一寄存器的值和另一寄存器的值 相减 并将结果保存在另一寄存器中,如:

sub x0, x1, x2        ; 将寄存器 x1 和 x2 的值相减后保存到寄存器 x0 中 

mul 乘

mul: 将某一寄存器的值和另一个寄存器的值 相乘 并将结果保存在另一寄存器中,如:

mul x0, x1, x2        ; 将寄存器 x1 和 x2 的值相乘后结果保存到寄存器 x0 中

sdiv 除

sdiv:(有符号数,对应 udiv: 无符号数)将某一寄存器的值和另一个寄存器的值 相除 并将结果保存在另一寄存器中,如:

sdiv x0, x1, x2       ; 将寄存器 x1 和 x2 的值相除后结果保存到寄存器 x0 中

and 位与

and: 将某一寄存器的值和另一寄存器的值 按位与 并将结果保存到另一寄存器中,如:

and x0, x0, #0xf      ; 将寄存器 x0 的值和常量 0xf 按位与后保存到寄存器 x0 中 

orr 逻辑或运算

orr: 将某一寄存器的值和另一寄存器的值 按位或 并将结果保存到另一寄存器中,指令格式:

ORR{条件}{S}  目的寄存器,操作数1,操作数2

ORR指令用于在两个操作数上进行逻辑戒运算,并把结果放置到目的寄存器中。操作数1应该是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数1的某些位。

如:

orr x0, x0, #9        ; 将寄存器 x0 的值和常量 9 按位或后保存到寄存器 x0 中

指令示例:

ORR R0,R0,#3      ;  该指令设置R0的0、1位,其余位保持不变。
ORR R0,R0,#0xd3   ;0xD3=1101 0111
                  ;将R0与0xD3作算数或运算,然后将结果返还给R0,即把r0的bit[7:6]和bit[4]和bit[2:0]置为1。

bic 掩码位清0

BIC指令的格式为:

BIC{条件}{S}  目的寄存器, 操作数1, 操作数2

BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器、被移位的寄存器、或一个立即数。操作数2为32位的掩码,如果在掩码中置了某一位1,则清除这一位。未设置的掩码位保持不变。

eor 位异或

eor: 将某一寄存器的值和另一寄存器的值 按位异或 并将结果保存到另一寄存器中,如:

eor x0, x0, #0xf      ; 将寄存器 x0 的值和常量 0xf 按位异或后保存到寄存器 x0 中 

str 寄存器值(X0~X31)写入内存

str: (store register) 将寄存器中的值写入到内存中,如:

str w9, [sp, #0x8]    ; 将寄存器 w9 中的值保存到栈内存 [sp + 0x8] 处 
str   r1,[r2]        ; 将r1中的值存到r2所指定的地址中
str   r1,[r2],#4  ;将r1中的值存到r2所指定的地址中, 同时r2=r2+4

strb 寄存器值(X0~X31)单字节写入内存

strb: (store register byte) 将寄存器中的值写入到内存中(只存储一个字节),如:

strb w8, [sp, #7]     ; 将寄存器 w8 中的低 1 字节的值保存到栈内存 [sp + 7] 处 

ldr 读取内存到寄存器(X0~X31)

ldr: (load register) 将内存中的值读取到寄存器中,如:

ldr x0, [x1]          ; 将寄存器 x1 的值作为地址,取该内存地址的值放入寄存器 x0 中 
ldr w8, [sp, #0x8]    ; 将栈内存 [sp + 0x8] 处的值读取到 w8 寄存器中 
ldr x0, [x1, #4]!     ; 将寄存器 x1 的值加上 4 作为内存地址, 取该内存地址的值放入寄存器 x0 中, 然后将寄存器 x1 的值加上 4 放入寄存器 x1 中 
ldr x0, [x1], #4      ; 将寄存器 x1 的值作为内存地址,取内该存地址的值放入寄存器 x0 中, 再将寄存器 x1 的值加上 4 放入寄存器 x1 中 
ldr x0, [x1, x2]      ; 将寄存器 x1 和寄存器 x2 的值相加作为地址,取该内存地址的值放入寄存器 x0 中 
​

ldrsb 读取内存一字节到寄存器(X0~X31)

ldrsb: (load register byte) 将内存中的值(只读取一个字节)读取到寄存器中,如:

ldrsb   w8, [sp, #7]    ; 将栈内存 [sp + 7] 出的 低 1 字节的值读取到寄存器 w8 中
​

stur 类str指令

stur:str 将寄存器中的值写入到内存中(一般用于 地址运算中),如:

stur w10, [x29, #-0x4]    ; 将寄存器 w10 中的值保存到栈内存 [x29 - 0x04] 处   
​

ldur 类ldr指令

ldur:ldr 将内存中的值读取到寄存器中(一般用于 地址运算中),如:

ldur w8, [x29, #-0x4]     ; 将栈内存 [x29 - 0x04] 处的值读取到 w8 寄存器中

stp 入栈指令(同时操作两个寄存器)

stp: 入栈指令(str 的变种指令,可以同时操作两个寄存器),如:

stp x29, x30, [sp, #0x10]   ; 将 x29, x30 的值存入 sp 偏移 16 个字节的位置 
​

ldp 出栈指令(同时操作两个寄存器)

ldp: 出栈指令(ldr 的变种指令,可以同时操作两个寄存器),如:

ldp x29, x30, [sp, #0x10]   ; 将 sp 偏移 16 个字节的值取出来,存入寄存器 x29 和寄存器 x30 

scvtf

scvtf: (Signed Convert To Float)带符号 定点数 转换为 浮点数,如:

scvtf   d1, w0      ; 将寄存器 w0 的值(顶点数,转化成 浮点数) 保存到 向量寄存器/浮点寄存器 d1 中

fcvtzs

fcvtzs: (Float Convert To Zero Signed)浮点数 转化为 定点数 (舍入为0),如:

fcvtzs w0, s0       ; 将向量寄存器 s0 的值(浮点数,转换成 定点数)保存到寄存器 w0 中

cbz

cbz: 和 0 比较(Compare),如果结果为零(Zero)就转移(只能跳到后面的指令);

cbnz

cbnz: 和非 0 比较(Compare),如果结果非零(Non Zero)就转移(只能跳到后面的指令);

cmp

cmp: 比较指令,相当于 subs,影响程序状态寄存器 CPSR ;

cset

cset: 比较指令,满足条件,则并置 1,否则置 0 ,如:

cmp w8, #2        ; 将寄存器 w8 的值和常量 2 进行比较
cset w8, gt       ; 如果是大于(grater than),则将寄存器 w8 的值设置为 1,否则设置为 0
​

brk

brk: 可以理解为跳转指令特殊的一种

LSL 逻辑左移

LSL: 逻辑左移

LSR 逻辑右移

LSR: 逻辑右移

MOV     R0, R2, LSR#8

ASR 算术右移

ASR: 算术右移

ROR 循环右移

ROR: 循环右移

adrp

adrp: 用来定位数据段中的数据用, 因为 aslr 会导致代码及数据的地址随机化, 用 adrp 来根据 pc 做辅助定位

B

b: (branch)跳转到某地址(无返回), 不会改变 lr (x30) 寄存器的值;一般是本方法内的跳转,如 while 循环,if else 等 ,如:

b LBB0_1      ; 直接跳转到标签 ‘LLB0_1’ 处开始执行
​

BL

bl: 跳转到某地址(有返回),先将下一指令地址(即函数返回地址)保存到寄存器 lr (x30)中,再进行跳转 ;一般用于不同方法直接的调用 ,如:

bl 0x100cfa754  ; 先将下一指令地址(‘0x100cfa754’ 函数调用后的返回地址)保存到寄存器 ‘lr’ 中,然后再调用 ‘0x100cfa754’ 函数
​

BLR

blr: 跳转到 某寄存器 (的值)指向的地址(有返回),先将下一指令地址(即函数返回地址)保存到寄存器 lr (x30)中,再进行跳转 ;如:

blr x20       ; 先将下一指令地址(‘x20’指向的函数调用后的返回地址)保存到寄存器 ‘lr’ 中,然后再调用 ‘x20’ 指向的函数
​

BR

br: 跳转到某寄存器(的值)指向的地址(无返回), 不会改变 lr (x30) 寄存器的值。

BRK

brk: 可以理解为跳转指令特殊的一种。

RET

ret: 子程序(函数调用)返回指令,返回地址已默认保存在寄存器 lr (x30) 中

MCR

MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

指令的语法格式:

MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

MCR2 p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

其中,<cond>为指令执行的条件码。当<cond>忽略时指令为无条件执行。MCR2中,<cond>为Ob1111,指令为无条件执行指令。

<opcode_1>为协处理器将执行的操作的操作码。对于CP15协处理器来说, <opcode_1>永远为0b000,当<opcode_1>不为0b000时,该指令操作结果不可预知。

<Rd>作为元寄存器的ARM寄存器,其值被传送到得协处理器寄存器中。

<Rd>不能为PC,当其为PC时,指令操作结果不可预知。

<CRn>作为目标寄存器的协处理器寄存器,其编号可能为C0,C1....C15。 <CRm>附加的目标寄存器或者原操作数寄存器,用于区分同一个编号的不同物理寄存器。当指令中不需要提供附加信息时,将C0指定为<CRm>,否则指令操作结果不可预知。 <opcode_2>提供附加信息,用于区别同一个编号的不同物理寄存器。当指令中指定附加信息时,省略<opcode_2>或者将其指定为0,否则指令操作结果不可预知。

MRC

MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断

指令的语法格式:

MRC{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

MRC2 p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

MCRR

写64bit的数据CP中,如CP15.

MCRR(从寄存器移到协处理器)将一对 ARM 寄存器传输到协处理器。该指令的目的由协处理器实现者定义。

MCRR{cond} coproc, #opcode3, Rt, Rt2, CRm
在哪里:
cond是一个可选的条件代码。请参阅条件执行。
Rt并且Rt2是要传输的 ARM 寄存器。
coproc是指令所针对的协处理器的名称。这通常是 p 的形式n,其中n是 0 到 15 范围内的整数。
CRm是一个协处理器寄存器。
Opcode3是一个可选的 4 位协处理器特定操作码。

写入64bit的数据,cntpct是内核的generic timer的寄存器,其是一个64bit的寄存器。

uint64_t cntv_cval_el0 = 0x1 << 35;
__asm__ __volatile__("MCRR  p15, 0, %Q0, %R0, c14\n\t"  : : "r" (cntv_cval_el0) : "memory");

MRRC

从协处理器移动到两个 ARM 内核寄存器会导致协处理器将值传输到两个 ARM 内核寄存器。如果没有协处理器可以执行该指令,则会产生未定义指令异常。

这是一个通用协处理器指令。一些字段没有由架构定义的功能,并且可供协处理器指令集设计者免费使用。这些是opc1CRm字段。但是,协处理器 CP8-CP15 是保留给 ARM 使用的,本手册定义了在-范围内时的有效MRRCMRRC2指令。有关详细信息,请参阅协处理器支持coproc``p8``p15

在包含虚拟化扩展的实现中,MRRC对系统控制寄存器的访问可能会被捕获到 Hyp 模式,这意味着尝试MRRC在除 Hyp 模式之外的非安全模式下执行指令,这在没有 Hyp 的情况下是允许的陷阱控件,生成一个 Hyp Trap 异常。有关更多信息,请参阅对管理程序的陷阱

MRRC<c> <coproc>, <opc>, <Rt>, <Rt2>, <CRm>
​

示例

读取64bit的数据,cntpct是内核的generic timer的寄存器,其是一个64bit的寄存器。

static inline u64 __arch_counter_get_cntpct(void)
{
    u64 cval;
​
    isb();
    asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
    return cval;
}

MRRC2

从协处理器移动到两个 ARM 内核寄存器会导致协处理器将值传输到两个 ARM 内核寄存器。如果没有协处理器可以执行该指令,则会产生未定义指令异常。

这是一个通用协处理器指令。一些字段没有由架构定义的功能,并且可供协处理器指令集设计者免费使用。这些是opc1CRm字段。但是,协处理器 CP8-CP15 是保留给 ARM 使用的,本手册定义了在-范围内时的有效MRRCMRRC2指令。有关详细信息,请参阅协处理器支持coproc``p8``p15

MRRC2<c> <coproc>, <opc>, <Rt>, <Rt2>, <CRm>
​

ISB

指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。

DMB

数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。

DSB

据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访 问操作——译者注)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/487053
推荐阅读
相关标签
  

闽ICP备14008679号