# 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) ![](./images/post-index.png) ### 32位版本 触发条件:`size` 字段 = 二进制 `10` 汇编格式:
`LDR , [], #` ### 64位版本 触发条件:`size` 字段 = 二进制 `11` 汇编格式:
`LDR , [], #` ### 该编码全部变体的解码逻辑 ``` 布尔变量 wback = 真; 布尔变量 postindex = 真; 整型 scale = size 字段转为无符号整数; 64位偏移量 offset = 将imm9字段符号扩展至64位; ``` ![](./images/practice-str.png) --- ## 二、前变址寻址(Pre-index) ### 指令位域划分(位31~0) ![](./images/pre-index.png) ### 32位版本 触发条件:`size` 字段 = 二进制 `10` 汇编格式:
`LDR , [, #]!` ### 64位版本 触发条件:`size` 字段 = 二进制 `11` 汇编格式:
`LDR , [, #]!` ### 该编码全部变体的解码逻辑 ``` 布尔变量 wback = 真; 布尔变量 postindex = 假; 整型 scale = size 字段转为无符号整数; 64位偏移量 offset = 将imm9字段符号扩展至64位; ``` ## 三、无符号偏移寻址模式(Unsigned offset) ### 指令二进制位域划分(位31~0) ![](./images/unsignedOffset.png) #### 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) ![](./images/ldr-iteral.png) #### 32位版本 生效条件:`opc == 00` 汇编格式:`LDR ,