# arm64_programming_practice
**Repository Path**: longlongint/arm64_programming_practice
## Basic Information
- **Project Name**: arm64_programming_practice
- **Description**: 《ARM64体系结构编程与实践》一书 配套实验参考代码
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 32
- **Created**: 2026-06-28
- **Last Updated**: 2026-07-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### 本地资料路径:
F:\baiduDownload\奔跑吧Linux合集 4季+死机专题+vim+git\奔跑吧Linux合集 4季+死机专题+vim+git视频\第3季 ARM64体系结构与编程
F:\baiduDownload\奔跑吧Linux合集 4季+死机专题+vim+git\奔跑吧Linux合集资料\第3季Arm配套资料\芯片手册\芯片原版
## 1. A64指令介绍
1. A64 指令集只能运行在aarch64环境中
2. 所有A64汇编指令都是32bits宽
表C1-2 通用寄存器、零寄存器以及栈指针命名
| 名称 | 位宽 | 编码值 | 说明 |
| ---- | ---- | ---- | ---- |
| Wn | 32位 | 0~30 | 0~30号通用寄存器 |
| Xn | 64位 | 0~30 | 0~30号通用寄存器 |
| WZR | 32位 | 31 | 零寄存器 |
| XZR | 64位 | 31 | 零寄存器 |
| WSP | 32位 | 31 | 当前栈指针 |
| SP | 64位 | 31 | 当前栈指针 |
### 补充说明(AArch64架构特性)
编码`31`是复用编码:CPU会根据指令上下文自动区分,该编码代表零寄存器(XZR/WZR)或是栈指针(SP/WSP);
- 以`W`开头 = 访问寄存器低32位;以`X`开头 = 访问完整64位寄存器;
- 零寄存器只读,读取永远得到数值0,写入操作无效;栈指针专门用于管理程序栈内存.
## A64指令分类
- 内存加载和存储指令
- 多字节内存加载和存储
- 算术和移位指令
- 移位操作
- 位操作指令
- 条件操作
- 跳转指令
- 独占访存指令
- 内存屏障指令
- 异常处理指令
- 系统寄存器访问指令
---
# 1. ldr指令和str指令
ARMv8架构也是基于指令加载和存储的架构(Load/Store Architecture)
加载/存储指令格式:
1. LDR 目标寄存器, <存储器地址> //把存储器地址的数据加载到目标寄存器中
2. STR 源寄存器, <存储器地址> //把源寄存器的值存储到存储器中
### 简要释义
- LDR(Load):读内存,将内存指定地址的数据读取放入寄存器
- STR(Store):写内存,将寄存器里的数据写入内存指定地址
这是ARM典型Load/Store架构的核心访存指令,运算指令只能操作寄存器,不能直接读写内存.
---
## 一、后变址寻址(Post-index)
### 指令位域划分(位31~0)

### 32位版本
触发条件:`size` 字段 = 二进制 `10`
汇编格式:
`LDR , [], #`
### 64位版本
触发条件:`size` 字段 = 二进制 `11`
汇编格式:
`LDR , [], #`
### 该编码全部变体的解码逻辑
```
布尔变量 wback = 真;
布尔变量 postindex = 真;
整型 scale = size 字段转为无符号整数;
64位偏移量 offset = 将imm9字段符号扩展至64位;
```

---
## 二、前变址寻址(Pre-index)
### 指令位域划分(位31~0)

### 32位版本
触发条件:`size` 字段 = 二进制 `10`
汇编格式:
`LDR , [, #]!`
### 64位版本
触发条件:`size` 字段 = 二进制 `11`
汇编格式:
`LDR , [, #]!`
### 该编码全部变体的解码逻辑
```
布尔变量 wback = 真;
布尔变量 postindex = 假;
整型 scale = size 字段转为无符号整数;
64位偏移量 offset = 将imm9字段符号扩展至64位;
```
## 三、无符号偏移寻址模式(Unsigned offset)
### 指令二进制位域划分(位31~0)

#### 32位版本
生效条件:`size = 二进制10`
汇编格式:
`LDR , [{, #}]`
#### 64位版本
生效条件:`size = 二进制11`
汇编格式:
`LDR , [{, #}]`
#### 该编码所有变体的解码逻辑
```
布尔变量 wback = 假;
布尔变量 postindex = 假;
整型 scale = 将size字段解析为无符号整数;
64位偏移量 offset = 对imm12做零扩展至64位后,再逻辑左移scale位;
```
### 所有编码通用注释
关于本条指令**受限型不可预知行为**的相关说明,请查阅附录K1《不可预知行为的架构约束》,具体可参考K1-7864页中`LDR (immediate)`章节.
### 汇编符号说明
| 符号 | 释义 |
|------|------|
| `` | 待传输数据的32位通用寄存器名,编码存放于Rt字段 |
| `` | 待传输数据的64位通用寄存器名,编码存放于Rt字段 |
| `` | 64位基址通用寄存器 或 栈指针SP,编码存放于Rn字段 |
| `` | 带符号字节偏移立即数,取值范围 -256 ~ 255,编码存放于imm9字段 |
| `` | 32位指令版本:可选正字节偏移立即数,必须是4的倍数,范围0~16380,默认值0;存入imm12时实际存储值为 `/4`
64位指令版本:可选正字节偏移立即数,必须是8的倍数,范围0~32760,默认值0;存入imm12时实际存储值为 `/8` |
### 所有编码共用解码流程
```
整型 n = 将Rn解析为无符号整数;
整型 t = 将Rt解析为无符号整数;
整型 regsize;
// 判定目标寄存器位宽
regsize = 若 size == 二进制'11' 则为64,否则为32;
整型 datasize = 8 左移 scale 位;
布尔变量 tag_checked = (wback为真) 或 (n不等于31);
```
### 所有编码共用操作逻辑
```
if (开启MTE内存标签扩展功能) then
设置本条指令为标签检查类指令(tag_checked);
定义64位变量 address;
定义datasize位变量 data;
布尔变量 wb_unknown = 假;
// 判定写回冲突场景:源基址与目标寄存器相同、且Rn不是31
if (wback为真 且 n == t 且 n != 31) then
c = 约束不可预知行为判定();
// 判定结果仅能为以下四类
assert c 属于 {约束_写回屏蔽, 约束_未知, 约束_未定义, 约束_NOP空操作};
匹配c的分支:
当 约束_写回屏蔽:wback = 假; // 屏蔽寄存器自动写回
当 约束_未知:wb_unknown = 真; // 写回行为结果未知
当 约束_未定义:触发未定义指令异常;
当 约束_NOP空操作:指令直接结束;
// 如果基址是栈指针SP(Rn编号=31)
if (n == 31) then
检查栈指针对齐合法性();
address = SP寄存器的值;
else
address = X[n]寄存器的值;
// 非后变址模式:先预计算有效地址
if (postindex为假) then
address = address + offset;
// 从内存读取指定长度数据
data = 内存[address, 字节长度=datasize/8, 普通访问类型];
// 将读取数据零扩展后写入目标寄存器
X[t] = 对data做零扩展至regsize位;
// 处理基址寄存器写回逻辑
if (wback为真) then
if (wb_unknown为真) then
address = 64位未知值;
elseif (postindex为真) then
address = address + offset;
// 写回更新基址/栈指针
if (n == 31) then
SP = address;
else
X[n] = address;
```
### 运行特性说明
若程序状态寄存器位`PSTATE.DIT = 1`,本条指令的执行耗时**不会随加载/存储的数据内容发生变化**(数据独立时序,抵御时序侧信道攻击).
## 四. 字面量寻址模式 LDR 指令(LDR (literal))
### 指令概述
**寄存器加载指令(字面量寻址)**:该指令利用程序计数器PC的值加上立即偏移量算出内存地址,从对应内存读取一个字数据,写入目标寄存器. 关于内存访问的相关说明,可查阅C1-189页《加载/存储寻址模式》章节.
### 指令二进制位域(位31~0)

#### 32位版本
生效条件:`opc == 00`
汇编格式:`LDR ,