Github 地址:carloscn/uncle-ben-os at car_lab_01 (github.com)
ARMv8 指令集介绍
- A64 指令集只能运行在 aarch64
-
所有 A64 汇编都是 32 bits 宽的
- 关注指令的应用、有什么 limitation
- A64 能拜访的地址数据是 64 位宽的
-
A64 反对全副的大写或者小写形式
- ARM 官网大写
- 利用应用小写
-
寄存器命名
- Wn 示意 32bits 宽的寄存器
- Xn 示意 64bits 宽的寄存器
- WZR 示意 32 位内容全为 0 的寄存器
- XZR 示意 64 位内容全为 0 的寄存器
- …
LDR 指令
LDR Xd, [Xn, $offset]
- 【释义】:将 Xn 寄存器中存储的地址 +offset 地址偏移存 组成一个新的地址,把这个地址外面存储的值放在 Xd 寄存器中。[]有取地址内存储的数值的含意。
-
【示例】:
- S1: 应用 MOV 指令把 0x80000 加载到 X1 寄存器:
MOV x1, 0x80000
(如果是一个数,而非 #0x80000, 则是一个地址) - S2: 应用 MOV 指令把 16 数值加载到 X3 寄存器:
MOV x3, 16
- S3: 应用 LDR 指令读取 X1 地址外面存储的值,存储到 X0 中:
LDR x0,[x1]
, 这个不容许 ->LDR x2,[0x80000]
- S4: 应用 LDR 指令读取 X1 + 8 地址外面存储的值,存储到 X2 中:
LDR x2,[x1, #8]
- S5: 应用 LDR 指令读取 (X1 + X3) 地址外面存储的值,存储到 X4 中:
LDR x4,[x1, x3]
- S6: 应用 LDR 指令读取 (X1+(X3<<3)) 地址外面存储的值,存储到 X5 中:
LDR x5,[x1,x3,lsl #3]
- S1: 应用 MOV 指令把 0x80000 加载到 X1 寄存器:
-
【留神】:
- 给的数不加任何标记的视为地址
- 须要给立刻数的场景而非地址的值,应用 #
- []有取地址值的意思
- LDR lsl 扩大指令,只反对 1 和 3
LDR x2,[x1, #8]
x1 的值 不会 被更新为 0x80008
-
【变基模式】:
- 前变基模式 pre-index:先更新偏移地址,后拜访地址
- 后变基模式 post-index:先拜访内存地址,再更新偏移地址
GDB-Tips
-
启动 GDB 和 QEMU 链接
> gdb-multiarch --tui benos.elf
gdb> c
gdb> target remote localhost:1234
gdb> b ldr_test
// 设定断点gdb> c
gdb> next
// 下一步gdb> info register
// 查看所有寄存器gdb> info x1 x2 x3
// 查看 x1/x2/x3 寄存器gdb> x 0x80000
// 读取内存 0x80000 值 32 位gdb> x/xg 0x80000
// 读取内存 0x80000 值 64 位