0%

arm64指令学习1-加载存储指令

加载存储指令

加载指令ldr

把存储器中的数据加载到目标寄存器中。一次操作8个字节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 指令格式:
ldr 目标寄存器, <存储器地址>

# 示例

mov x2, 0x8000 # 设置x2 = 0x8000
ldr x1, [x2, #8]! # 前变基模式, x2值先 +8, 再作为地址,x1取该地址的值
ldr x5, [x1, x3, lsl #3] # 读取 x1 + (x3<<3)的地址内容到x5
ldr x1, [x2], #8 # 后变基模式,先以x2值为地址,取值赋值到x1, x2值再加8

#define LABEL 0x20
ldr x1, LABEL # 取pc + LABEL值为地址,取值赋值给x1
ldr x1, =LABEL # x1 = 0x20 // 伪指令

.global string1
string1:
.string "boot el"

ldr x1, string1 # 加载 boot el的ASCII码到x1寄存器
ldr x1, =string1 # 加载string1的地址到x1寄存器

.global my_data
my_data:
.word 0x44

ldr x1, my_data # 加载my_data的值0x44 到x1
ldr x1, =mydata # 加载my_data的地址到x1

存储指令str

把寄存器中的数据保存到存储器中。一次操作8个字节。

1
2
3
4
5
6
7
8
9
10
11
12
# 指令格式:
str 源寄存器, <存储器地址>

# 示例

mov x2, 0x8000 # 设置x2 = 0x8000
mov x1, =0x30
str x1, [x2, #8]! # 前变基模式, x2值先 +8, 再作为地址,将x1的值存储到该地址
str x1, [x2, x3, lsl #3] # 存储x1值到 x2 + (x3<<3)的地址内容
str x1, [x2], #8 # 后变基模式,先以x2值为地址,x1的值存储到该地址, x2值再加8


mov指令

可以加载一个16位的立即数到寄存器。或者16位立即数并左移16,32,48位

1
2
mov xd, 0x8000 

多字节的加载和存储指令ldp和stp指令

ldp和stp可以一条指令加载和存储16个字节,效率比ldr、str提高一倍。

1
2
3
4
5
6
ldp x3, x7, [x0] // x0 ==> x3, x0+8 ==> x7 

stp x1, x2, [x3] // x1 ==> x3, x2 ==> x3+8

stp x1, x1, [x2], #16 // 把x1 ==> x2, x1 ==> x2+8, 然后x2=x2+16

汇编函数编写

在C语言调用汇编函数,可以是用extern声明,函数的参数存储在X0~X7。

1
2
3
4
5
6
7
8
9
extern void mem_test();


# 把0x8000 存储到0x8008中
.global mem_test
mem_test:
mov x2, 0x8000
mov x1, 0x8008
str x2, [x1]

cmp x1, x2
b.cc lb # 如果x1 < x2 ,跳转到1标签


行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

欢迎关注

博客地址: https://fishmwei.github.io

掘金主页: https://juejin.cn/user/2084329776486919