1. Arm64汇编 lsr 指令
LSR是ARM架构的位移动指令,用于逻辑右移操作。它将第一个操作数的位向右移动指定位数,并根据需要将符号位(在有符号数操作中)扩展到空出来的位。
语法:
LSR{条件}{S} 移位量,寄存器
条件是可选的,指定为如 EQ、NE 等,用来指明只有在特定条件下才能执行指令。
S 是可选的,指定为 S 表示指令应该影响 CPSR 中的条件标志位,不指定则不影响条件标志位。
移位量是一个立即数,用来指定位移动的位数,范围通常是0到31。
寄存器是一个通用寄存器,包含要移位的值。
实例代码:
LSR R0, R0, #5 ; 将寄存器R0中的值逻辑右移5位
这条指令将寄存器R0中的值移动5位右边的位进入CPSR中,左边空出的位用0填充,符号位扩展也遵循这个规则。
2. Arm64汇编 add 指令
ADD 用于执行加法操作。它可以用于两个通用寄存器、一个通用寄存器和一个寄存器的内存地址、或者一个寄存器和一个立即数之间的加法。
以下是一些使用 ADD 指令的例子:
两个通用寄存器之间的加法:
ADD w0, w1, w2 ; 将 w1 和 w2 的内容相加,结果存储在 w0 中
通用寄存器与内存地址之间的加法:
ADD w0, w1, [x2] ; 将 w1 和内存地址 x2 指向的值相加,结果存储在 w0 中
通用寄存器与立即数之间的加法:
ADD w0, w1, #10 ; 将 w1 和立即数 10 相加,结果存储在 w0 中
请注意,ADD 指令可以有条件执行,例如,ADD 指令可以跟有条件后缀,如 EQ、NE、HS 等,这样只有在特定条件满足时才会执行加法操作。
3. Arm64汇编 orr 指令
orr 是 ARM 汇编语言中的一个逻辑指令,用于执行两个值的按位或操作。orr 指令可以对两个寄存器或寄存器和立即数进行操作。
语法格式如下:
orr {<cond>} <rd>, <rn>, <operand2>
<cond> 是可选的条件代码。
<rd> 是目标寄存器,用于保存结果。
<rn> 是第一个源寄存器,其内容将被操作。
<operand2> 是第二个源操作数,可以是一个寄存器或立即数值。
实例代码:
orr r0, r1, #0xF ; 将寄存器 r1 的值与立即数 0xF 进行按位或操作,结果存储在 r0 中
orr r2, r3, r4 ; 将寄存器 r3 的值与寄存器 r4 的值进行按位或操作,结果存储在 r2 中
在这个例子中,r0 将会是 r1 或上 0xF 的结果,r2 将会是 r3 或 r4 的结果。
4. arm64汇编 str 指令
str 是 ARM 汇编语言中的一个指令,用于将数据从寄存器传送到内存地址。####在 ARM 架构中,有多种不同的 str 指令,用于处理不同的数据类型和操作模式。
以下是一些使用 str 指令的示例:
(1) 将一个32位的寄存器值存储到内存中:
str r1, [r2]
这条指令会将寄存器 r1 的值存储到 r2 寄存器值指定的内存地址中。
(2) 将一个64位的寄存器值存储到内存中:
str r1, [r2]
str r1, [r2, #8]!
第一条指令会将 r1 的低64位存储到内存地址中。第二条指令会将 r1 的高64位存储到内存地址中,并且更新 r2 的值(使用后续的内存地址)。
(3) 将一个32位的寄存器值存储到带有偏移的内存地址中:
str r1, [r2, #16]
这条指令会将 r1 的值存储到 r2 的值加上16后得到的内存地址中。
(4) 将一个32位的寄存器值存储到带有索引的内存地址中:
str r1, [r2, lr]
这条指令会将 r1 的值存储到 r2 的值加上 lr 寄存器值得到的内存地址中。
(5) 将一个32位的常数存储到内存中:
str w3, [sp, #-4]!
这条指令会将常数w3存储到栈上,并更新 sp 寄存器的值(向下增长)。
(6) 将一个16位的寄存器值存储到内存中:
strh r1, [r2]
这条指令会将 r1 的低16位存储到内存地址中。
(7) 将一个8位的寄存器值存储到内存中:
strb r1, [r2]
这条指令会将 r1 的低8位存储到内存地址中。
(8) 使用 str 指令复制数据:
str r1, [r2]
这条指令会将 r1 寄存器中的值复制到 r2 寄存器指定的内存地址中。
注意:在使用 str 指令时,确保目标地址是可写的,否则会产生异常。
补充:这里给出不同指令下进行数据操作的位数:
ldrb/strb 8位操作
ldrh/strh 16位操作
ldr/str 32位操作
ldrd/strd 64位操作
5. Arm64汇编 .macro 指令
.macro 是 ARM 汇编语言中用于定义宏的指令。宏是一段可以重复使用的汇编代码,类似于 C 语言中的宏。使用 .macro 指令定义宏,使用 .endm 指令结束宏定义。
下面是一个简单的 .macro 使用例子:
.macro BLK_MOV_ALIGNED_I4 inptr, outptr, len, incr
mov x0, \inptr
mov x1, \outptr
mov x2, \len
mov x3, \incr
blk_mov_aligned_i4 x0, x1, x2, x3
.endm
在这个例子中,BLK_MOV_ALIGNED_I4 是宏的名称。宏接受四个参数:inptr, outptr, len, 和 incr。这些参数在宏的代码中通过 \param 的方式使用,其中 \inptr 代表输入指针参数,\outptr 代表输出指针参数,依此类推。
当宏被调用时,例如通过 BLK_MOV_ALIGNED_I4 x0, x1, x2, x3,它将把 x0, x1, x2, x3 分别赋值给 \inptr, \outptr, \len, \incr,然后执行 blk_mov_aligned_i4 x0, x1, x2, x3 指令。
注意:这只是一个假设的 blk_mov_aligned_i4 实现的宏例子,实际的 blk_mov_aligned_i4 是内核提供的一个函数,宏用于封装函数调用的参数。
6. Arm64汇编 mov 指令
在ARM架构中,mov 指令用于数据传送。在ARMv8 (arm64) 汇编中,mov 指令可以用于不同的数据类型,包括通用寄存器,寄存器的特定位,或者是寄存器和内存之间的数据传送。
以下是一些使用 mov 指令的例子:
(1) 将一个常数加载到寄存器中:
mov x0, #0x12345678 // 将常数0x12345678加载到x0寄存器中
(2) 将一个寄存器的值复制到另一个寄存器:
mov x1, x0 // 将x0寄存器中的值复制到x1寄存器中
(3) 将内存地址中的值加载到寄存器中:
mov x2, [x1] // 将x1寄存器指向的内存地址中的值加载到x2寄存器中
(4) 将一个特定的位从一个寄存器复制到另一个寄存器:
movk x0, #0x12, lsl #16 // 将0x12左移16位后,加载到x0寄存器的高16位中
(5) 将一个寄存器的值复制到另一个特定的寄存器(例如,将程序计数器的值复制到x0寄存器):
mov x0, pc // 将程序计数器的值复制到x0寄存器中
(6) 将一个寄存器的值复制到另一个特定的寄存器(例如,将链接寄存器x30的值复制到x0寄存器):
mov x0, x30 // 将链接寄存器的值复制到x0寄存器中
注意:在使用 mov 指令时,确保目标寄存器和源操作数的大小是兼容的,例如,不能直接将一个32位的值移动到一个64位的寄存器中,除非使用适当的扩展指令(如 movw 或 movn)。
7. Arm64汇编 b.ls 指令
b.ls 是一条条件分支指令,在 ARM 64 位汇编中,用于“less than and equal”的条件分支,即当比较的两个值中一个小于或等于另一个时,程序会跳转到指定的位置执行。
这条指令的全称是 "Branch Less Than or Equal",其语法格式如下:
b.ls <target_address>
其中 <target_address> 是你想要跳转到的地址。这条指令需要和状态寄存器中的条件标志一起工作,比如之前的一个比较指令 cmp 或者 ccmp 等可以设置条件标志的指令。
下面是一个使用 b.ls 的简单例子:
cmp x0, x1 // 比较寄存器x0和x1
b.ls label // 如果x0小于或等于x1,则跳转到label处执行
在这个例子中,cmp 指令用于比较寄存器 x0 和 x1,然后 b.ls 指令会检查比较的结果,如果 x0 小于或等于 x1,则程序会跳转到标签 label 指定的位置执行。
注意:b.ls 是 ARM 汇编的一个示例,具体的汇编语言和指令集可能会根据不同的处理器架构有所不同。
8. Arm64汇编 adrp 指令
adrp 是 ARM 64 位汇编语言中的一个地址相关的指令(Address Related Pointer),用于加载一个30位有符号的位移量到目标寄存器,用于支持大型内存页的访问。
adrp 指令不直接支持绝对地址计算,它通常与另一个指令 add 或 ldr 配合使用。adrp 指令生成一个31位有符号的位移量,通常用于加载大型内存页的基地址,然后通过 add 或 ldr 指令与一个32位的偏移量组合成最终的有效地址。
下面是一个使用 adrp 和 add 指令的例子:
adrp x0, my_data@PAGE // 加载数据段的基地址
add x0, x0, my_data@PAGEOFF // 加上偏移量得到具体地址
在这个例子中,my_data 是一个数据段的标签,汇编器会将它转换成一个32位的偏移量和一个使用 adrp 的基地址。这样,通过 adrp 指令我们得到了数据段的基地址,然后通过 add 指令我们加上偏移量得到了数据段中特定位置的实际有效虚拟地址。
提示:AI自动生成,仅供参考
9. arm64汇编 ldr指令
LDR 是 ARM 汇编中的一个 load register 指令,用于将数据从内存中加载到寄存器中。对于 ARM64 汇编,LDR 指令有多种变体,用于处理不同的数据加载和地址计算需求。
以下是一些使用 ARM64 汇编语言中 LDR 指令的示例:
将一个常量加载到寄存器中:
ldr x0, [0x12345678] // 将内存地址 0x12345678 处的值加载到寄存器 x0 中
将一个地址处的值加载到寄存器中,该地址是另一个寄存器的偏移量:
ldr x0, [x1, #0x10] // 将内存地址为 x1 寄存器值加上 0x10 的地址处的值加载到 x0 寄存器中
将一个符号地址处的值加载到寄存器中:
ldr x0, LABEL // 将标签 LABEL 表示的地址处的值加载到 x0 寄存器中
// ...
LABEL:
.quad 0x12345678 // 一些数据
将一个地址处的值加载到寄存器中,该地址是另一个寄存器的值与一个常数的和:
ldr x0, [x1, #0x10]! // 将内存地址为 x1 寄存器值加上 0x10 的地址处的值加载到 x0 寄存器中,同时将新地址写回到 x1 寄存器
使用 LDR 指令加载一个函数指针到寄存器中:
ldr x16, .LPIC0 // 加载一个 PIC (Position Independent Code) 偏移量到 x16 寄存器
// ...
.LPIC0:
.quad LPIC-.-
在使用 LDR 指令时,确保你的操作数和操作对应的寄存器是兼容的,并且考虑到 ARM64 寄存器的命名规则。此外,还需要注意指令的字节序和对齐问题。
10. arm64汇编 bl 指令
bl 是 ARM 汇编语言中的一个跳转指令,用于调用子程序。bl 指令在跳转之前会将下一条指令的地址保存在链接寄存器(LR)中,这样子程序在返回时可以正确继续执行。
bl 指令的格式如下:
bl <target_label>
其中 <target_label> 是你想要跳转到的子程序的标签。
例如,假设你有一个名为 subroutine 的子程序,你可以使用 bl 指令来调用它:
bl subroutine
在 subroutine 子程序的结尾,它应该使用 bx 或 b 指令来返回到保存在 LR 中的地址:
bx lr
或者
b *lr
这样,执行 bl subroutine 后,当 subroutine 子程序执行完毕后,执行流会回到 bl 指令之后的指令继续执行。
11. arm64汇编 stp 指令
stp 是 ARM 汇编语言中的一个指令,用于将一组寄存器的值存储到内存中。stp 是 "Store Registers in Pair" 的缩写。
语法:
stp { xn | sp }, { xn | sp }, [r], {#imm}
参数:
{ xn | sp } 是一个寄存器,可以是 x30(通常是 lr 或链接寄存器)或 sp(堆栈指针)。
{ xn | sp } 是另一个寄存器,用于与第一个寄存器配对。
[r] 是目标内存地址的基地址寄存器。
{#imm} 是一个可选的偏移量,用于指定存储位置的具体偏移量。
示例代码:
stp x29, x30, [sp, -16]! // 将 x29 和 x30 压栈,并更新 sp 的值
在这个例子中,stp 指令将寄存器 x29 和 x30 的值存储到当前堆栈顶部,然后将堆栈顶部向下移动 16 字节,并更新堆栈指针 sp。后缀 ! 表示对寄存器 sp 进行修改。######
12. arm64汇编 b.ne 指令
b.ne 是 ARM 汇编语言中的一个条件分支指令,它的全称是 "Branch if Not Equal",也就是当两个操作数不相等时才会跳转。
这个指令通常用于比较两个寄存器或者寄存器和立即数的值,然后根据比较结果是否相等来决定是否跳转到另一个标签(Label)或者指定的地址。
下面是一个使用 b.ne 指令的简单例子:
cmp x0, x1 // 比较寄存器x0和x1的值
b.ne label // 如果不相等,跳转到标签label处执行
在这个例子中,cmp 指令用于设置条件标志位,根据 x0 和 x1 的值进行比较。b.ne 指令检查不相等(NE)标志位,如果该标志被设置(表示x0不等于x1),则执行跳转到标签 label。
需要注意的是,b.ne 是一个短跳转指令,它的跳转范围是有限的,通常在当前指令的后面或者前面128MB范围内。#######如果需要更远的跳转,你应该使用 b 指令或其他分支指令。
13. arm64汇编 cmp 指令
CMP 是 ARM 汇编语言中的一个指令,用于比较两个操作数。当两个操作数作减法时,如果 Minuend(被减数)大于 Subtrahend(减数),则结果为正;如果 Minuend(被减数)小于 Subtrahend(减数),则结果为负;如果两者相等,结果为零。
CMP 指令不会改变操作数本身,只会设置一些特殊的程序状态寄存器(PSR)的标志位,这些标志位可以用来决定接下来应该执行什么样的代码分支。
下面是一些使用 CMP 指令的例子:
(1) 基本的比较操作:
cmp r0, r1 @ 将寄存器 r0 的值和 r1 的值进行比较
(2) 比较立即数:
cmp r0, #0 @ 将寄存器 r0 的值和立即数 0 进行比较
(3) 比较并根据结果决定是否跳转:
cmp r0, r1
beq next @ 如果 r0 等于 r1,则跳转到标签 next 的指令
(4) 比较数组中的元素:
ldr r2, [r0], #4 @ 加载数组的下一个元素到 r2
cmp r2, r1 @ 将 r2 和 r1 进行比较
bne difference @ 如果 r2 和 r1 不相等,则跳转到标签 difference 的指令
注意:CMP 指令不会改变操作数本身,只会改变状态寄存器的标志位。如果你需要保留操作数用于其他目的,你应该在执行 CMP 指令后将操作数拷贝到另一个寄存器。
14. Arm64汇编 dc 指令
在ARM架构中,DC是一个用于数据复制的指令,通常用于初始化数据。DC指令是ARM汇编器的扩展,用于在ELF (Executable and Linkable Format) 文件中生成一个专用的 .data.rel.ro 节。
DC指令的语法如下:
DC <constant> ; 复制一个常量到寄存器
DC { <constant_expression> } ; 复制一个常量表达式到寄存器
DC { <symbol> } ; 复制一个符号的地址到寄存器
DC { :<alignment> } ; 设置下一个数据标签的对齐
DC { ^ } ; 结束数据标签的定义
例如,以下是一个使用DC指令的简单ARM64汇编代码片段:
.data
.align 3
my_data:
DC 42 ; 将常量42初始化到一个字
DC 23 ; 将常量23初始化到下一个字
DC {my_symbol} ; 将符号my_symbol的地址初始化到一个字
DC {^} ; 结束数据初始化
在这个例子中,my_data 被初始化为包含四个字,分别是42, 23, my_symbol的地址,和一个结束标记。这种初始化方法通常用于初始化数组或者其他数据结构。
15. Arm64汇编 adr_l 指令
ADR_P 是 ARM 汇编器的一个指令,用于生成相对于 PC 的地址。它是 ADR 指令的一个变种,用于处理大于 4KB 的加载。
ADR_P 指令的语法如下:
ADR_P <register>, <expression>
其中 <register> 是目标寄存器,<expression> 是目标地址。
这个指令会尝试生成一个有效的地址,但是如果目标地址超出了 ADR_P 指令的有效范围(即,目标地址与当前 PC 的偏移量超过了 2^12 - 1 字节),那么这个指令将失败。
例如,如果你有一个标签 .label 在 4KB 之后,你可以使用 ADR_P 来加载它的地址:
adrp x0, .label
add x0, x0, :lo12:.label
这里,adrp 用于获取 .label 的高 32 位地址,add 用于获取低 12 位的偏移量。
注意:ADR_P 是在 ARMv8-A 架构中引入的,因此它不能在不支持此功能的旧架构中使用。
16. Arm64汇编 mov_q 指令
movq 是一个用于64位操作数的指令,用于将数据从一个位置移动到另一个位置。
17. arm64汇编 ret 指令
在ARM架构中,ret 指令用于从子程序返回到调用者。在ARMv8-A (arm64) 汇编中,ret 指令可以用于从子程序返回并恢复程序状态。
ret 指令的基本语法如下:
ret{cond}
其中 {cond} 是可选的条件代码。如果不指定,则默认条件代码为 al (即所有条件码)。
下面是一个简单的例子,展示了如何在ARM64汇编中使用 ret 指令:
sub sp, sp, #0x20 // 分配栈空间
stp x29, x30, [sp, #0x10]! // 保存调用者的链接寄存器和程序计数器
// ...子程序代码 ...
ldp x29, x30, [sp], #0x20 // 恢复调用者的链接寄存器和程序计数器
ret // 返回到调用者
在这个例子中,我们在调用子程序前保存了链接寄存器 x29 (fp) 和程序计数器 x30 (lr),在子程序结束前恢复它们,并使用 ret 指令返回到调用者。
18. Arm64汇编 ldp 指令
ldp 是 ARM 汇编语言中用于从寄存器组或栈中加载双精度浮点寄存器(FP Double-precision)的指令。它用于从内存地址加载 128 位的数据到两个浮点寄存器(通常是单独的浮点寄存器,但也可以是一个的高 64 位和另一个的低 64 位)。
语法如下:
LDP <Wt1>, <Wt2>, [<Xn|SP>], #<imm>
LDP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!
LDP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
LDP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
这里 <Wt1> 和 <Wt2> 是目标浮点寄存器,<Xn|SP> 是基址寄存器,<imm> 是一个常量偏移量。
例子:
ldp x29, x30, [sp], #0x20 // 将栈上偏移为 sp 的 32 字节处的数据加载到 x29 和 x30,然后 sp 增加 0x20
在这个例子中,ldp 指令用于从当前的栈指针 sp 所指向的位置加载两个 64 位的值到浮点寄存器 x29 和 x30,然后更新栈指针 sp 增加 0x20 字节。
标签:x1,15,r1,指令,Arm64,寄存器,x0,加载,内存 From: https://www.cnblogs.com/hellokitty2/p/18293178