ARM 汇编基础

ARM 汇编是嵌入式开发、操作系统底层编程和性能优化的核心技能之一。以下是一份系统的 ARM 汇编指令教学指南,涵盖基础语法、核心指令、编程模式和实用示例。

​1. ARM 汇编基础

​ 1.1 寄存器
ARM 架构(32位)包含 ​16 个通用寄存器​(R0-R15),其中部分有特殊用途:

​R0-R12:通用寄存器,用于存储数据和地址。
​R13 (SP):栈指针(Stack Pointer),指向当前栈顶。
​R14 (LR):链接寄存器(Link Register),保存函数返回地址。
​R15 (PC):程序计数器(Program Counter),指向下一条要执行的指令。
​CPSR:当前程序状态寄存器(Condition Program Status Register),存储条件标志(如 Z、N、C、V)。

​2. ARM 汇编指令格式

ARM 指令通常遵循以下格式:

<操作码>{条件码}{S} <目标寄存器>, <操作数1>, <操作数2>
​条件码​(可选):如 EQ(相等)、NE(不等)、GT(大于)。
​S​(可选):更新 CPSR 标志(如 ADDS 会更新 Z/N/C/V 标志)。
​操作数:可以是寄存器、立即数或内存地址。

​3. 核心指令分类

​3.1 数据传输指令
MOV:将数据从一个寄存器或立即数复制到另一个寄存器。

MOV R0, #42       ; R0 = 42
MOV R1, R0        ; R1 = R0

LDR/STR:从内存加载数据到寄存器(Load)或从寄存器存储到内存(Store)。

LDR R0, [R1]      ; R0 = 内存地址[R1]处的值
STR R2, [R3, #4]  ; 将 R2 的值存储到内存地址 R3 + 4

​3.2 算术运算
ADD/SUB:加法和减法。

ADD R0, R1, R2    ; R0 = R1 + R2
SUB R3, R3, #1    ; R3 = R3 - 1

MUL/MLA:乘法和乘加。

MUL R0, R1, R2    ; R0 = R1 * R2
MLA R0, R1, R2, R3 ; R0 = R1 * R2 + R3

​3.3 逻辑运算
AND/ORR/EOR/BIC:按位与、或、异或、位清除。

AND R0, R1, #0xFF ; R0 = R1 & 0xFF(取低8位)
BIC R0, R1, #0x3  ; R0 = R1 & ~0x3(清除最低2位)

​3.4 比较与分支
CMP:比较两个操作数并更新 CPSR。

CMP R0, R1        ; 计算 R0 - R1,更新标志位

B/BL:无条件跳转(Branch)或带链接的跳转(Branch with Link,用于函数调用)。

B   loop          ; 跳转到标签 loop
BL  my_function   ; 调用函数 my_function,返回地址存入 LR

​3.5 栈操作
PUSH/POP:压栈和弹栈操作(需指定寄存器列表)。

PUSH {R0, R1, LR} ; 将 R0, R1, LR 压入栈
POP  {R0, R1, PC} ; 从栈中恢复 R0, R1,并将返回地址写入 PC(函数返回)

​4. 寻址模式

​4.1 立即数寻址
使用 # 前缀表示立即数:

MOV R0, #0x100    ; R0 = 0x100

​注意:ARM 立即数需满足特定规则(如 8 位有效位 + 移位)。
​4.2 寄存器间接寻址
通过寄存器中的地址访问内存:

LDR R0, [R1]      ; R0 = 内存地址[R1]处的值
STR R2, [R3, #4]  ; 存储到地址 R3 + 4

​4.3 基址变址寻址
支持偏移、前变址和后变址:

LDR R0, [R1, #8]! ; 前变址:R1 = R1 + 8,然后 R0 = [R1]
LDR R0, [R1], #8  ; 后变址:R0 = [R1],然后 R1 = R1 + 8

​5. 控制结构

​5.1 条件分支
根据 CPSR 标志跳转:

CMP R0, #10        ; 比较 R0 和 10
BGT greater_than    ; 若 R0 > 10,跳转到 greater_than

​5.2 循环
使用条件分支实现循环:

MOV R0, #0         ; 初始化计数器
loop:ADD R0, R0, #1   ; 计数器加1CMP R0, #5BLT loop         ; 若 R0 < 5,继续循环

​6. 函数调用

遵循 ​AAPCS​(ARM Architecture Procedure Call Standard)规范:

​参数传递:前 4 个参数通过 R0-R3 传递,后续参数通过栈传递。
​返回值:通过 R0 返回。
​保存寄存器:被调用函数需保护 R4-R11、SP、LR 等寄存器。
​示例:函数调用

.global main
main:MOV R0, #5       ; 参数 n = 5BL  factorial    ; 调用 factorial 函数BX  LR           ; 返回factorial:PUSH {R4, LR}    ; 保存寄存器MOV R4, R0       ; 保存参数到 R4CMP R4, #1MOVEQ R0, #1     ; 若 n == 1,返回 1POPEQ {R4, PC}   ; 恢复寄存器并返回SUB R0, R4, #1   ; 计算 n-1BL  factorial    ; 递归调用 factorial(n-1)MUL R0, R4, R0   ; R0 = n * factorial(n-1)POP {R4, PC}     ; 恢复寄存器并返回

​7. 常见问题与调试

​7.1 立即数限制
如果立即数过大,需分步加载或使用 LDR 伪指令:

LDR R0, =0x12345678 ; 加载任意32位立即数(编译器自动处理)

​7.2 条件执行
几乎所有 ARM 指令都可条件执行:

ADDEQ R0, R1, R2    ; 仅在 Z 标志置位时执行加法

​7.3 调试工具
​GDB:使用 arm-none-eabi-gdb 调试汇编代码。
​QEMU:模拟 ARM 硬件环境。
​Keil/STM32CubeIDE:针对嵌入式硬件的集成调试环境。

8. 完整示例:计算阶乘

.global main
main:MOV R0, #5       ; 计算 5!BL  factorialB   exitfactorial:CMP R0, #1       ; 基准条件:n == 1MOVEQ PC, LR     ; 若满足,直接返回PUSH {R0, LR}    ; 保存当前 n 和返回地址SUB R0, R0, #1   ; n = n - 1BL  factorial    ; 递归调用 factorial(n-1)POP {R1, LR}     ; 恢复原 n 到 R1 和返回地址MUL R0, R1, R0   ; R0 = n * factorial(n-1)BX  LR           ; 返回exit:; 此处可添加退出代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37794.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年渗透测试面试题总结- 某亭-安全研究员(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、SQL注入过滤单引号绕过方法 二、MySQL报错注入常用函数 三、报错注入绕WAF 四、MySQL写文件函数…

MacOS安装 nextcloud 的 Virtual File System

需求 在Mac上安装next cloud实现类似 OneDrive 那样&#xff0c;文件直接保存在服务器&#xff0c;需要再下载到本地。 方法 在 官网下载Download for desktop&#xff0c;注意要下对版本&#xff0c;千万别下 Mac OS默认的那个。 安装了登录在配置过程中千万不要设置任何同…

1.8 函数的连续性和间断点

1.连续的定义 2.间断点的定义 3.间断点的分类

Unity 云渲染本地部署方案

Unity Render Streaming 云渲染环境搭建 0.安装 Unity Render Streaming 实现原理: 服务器与客户端实现功能包括: 详细内容见官方文档&#xff1a; 官方文档: https://docs.unity3d.com/Packages/com.unity.renderstreaming3.1/manual/tutorial.html Unity 流送云渲染介绍: …

每日一题力扣3248.矩阵中的蛇c++

3248. 矩阵中的蛇 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int finalPositionOfSnake(int n, vector<string>& commands) {int i 0;int j 0;for (int k0;k<commands.size();k) {if (commands[k] "RIGHT")j;else if (comma…

本地基于Ollama部署的DeepSeek详细接口文档说明

前文&#xff0c;我们已经在本地基于Ollama部署好了DeepSeek大模型&#xff0c;并且已经告知过如何查看本地的API。为了避免网络安全问题&#xff0c;我们希望已经在本地调优的模型&#xff0c;能够嵌入到在本地的其他应用程序中&#xff0c;发挥本地DeepSeek的作用。因此需要知…

FPGA 以太网通信(三)

一、UDP协议 UDP&#xff08;User Datagram Protocol Protocol&#xff09;&#xff0c;即用户数据报协议&#xff0c;是一种面向无连接的传输层协议。UDP和TCP协议都属于传输层协议&#xff0c;在网络传输中同一 IP 服务器需要提供各种不同的服务&#xff0c;为了区别不同的服…

期刊分区表2025年名单下载(经济学、管理学)

2025年期刊分区表包括SCIE、SSCI、A&HCI、ESCI和OAJ&#xff0c;共设置了包括自然科学、社会科学和人文科学在内的21个大类 本次分享的是期刊分区表2025年名单经济学类、管理学类&#xff0c;一共7631025条 一、数据介绍 数据名称&#xff1a;期刊分区表2025年名单 数据…

如何在MCU工程中启用HardFault硬错误中断

文章目录 一、HardFault出现场景二、启动HardFault三、C代码示例 一、HardFault出现场景 HardFault&#xff08;硬故障&#xff09; 错误中断是 ARM Cortex-M 系列微控制器中一个较为严重的错误中断&#xff0c;一旦触发&#xff0c;表明系统遇到了无法由其他异常处理机制解决…

智能体开发革命:灵燕平台如何重塑企业AI应用生态

在AI技术深度渗透产业的今天&#xff0c;**灵燕智能体平台**以“全生命周期管理”为核心&#xff0c;为企业提供从智能体开发、协作到落地的闭环解决方案&#xff0c;开创了AI应用工业化生产的新模式。 三位一体的智能体开发体系 1. Agent Builder&#xff1a;零门槛构建专属…

机器学习之支持向量机(SVM)算法详解

文章目录 引言一、 什么是支持向量机&#xff08;SVM&#xff09;二、 SVM的基本原理三、数学推导1.线性可分情况2. 非线性可分情况3. 核函数 四、SVM的优缺点优点&#xff1a;缺点&#xff1a; 五、 应用场景六、 Python实现示例七、 总结 引言 支持向量机&#xff08;Suppor…

【C++进阶】深入探索类型转换

目录 一、C语言中的类型转换 1.1 隐式类型转换 1.2. 显式类型转换 1.3.C语言类型转换的局限性 二、C 类型转换四剑客 2.1 static_cast&#xff1a;静态类型转换&#xff08;编译期检查&#xff09; 2.2 dynamic_cast&#xff1a;动态类型转换&#xff08;运行时检查&…

机器学习之KL散度推导

机器学习之KL散度推导 预备知识 熵、交叉熵、条件熵 熵 (Entropy) 这一词最初来源于热力学。1948年&#xff0c;克劳德爱尔伍德香农将热力学中的熵引入信息论&#xff0c;所以也被称为香农熵 (Shannon entropy)、信息熵 (information entropy)。 对于具体熵的定义和用法推荐…

使用PlotNeuralNet绘制ResNet50模型

一、下载所需软件 1、下载MikTex 作用:将.tex文件转换为PDF文件 下载官网链接:Getting MiKTeX 2、下载Git 作用:将PlotNeuralNet库从GitHub上下载下来,在cmd使用命令行: git clone https://github.com/SamuraiBUPT/PlotNeuralNet-Windows.git 就可以将PlotNeuralNet…

10分钟打造专属AI助手:用ms-swift实现自我认知微调

想象一下&#xff0c;你是辛辛苦苦利用开源模型打造一个专属的AI产品助手。这个助手不仅能高效解答客户的问题&#xff0c;还能自豪地告诉大家&#xff1a;“我是某某打造的某某助手&#xff0c;代表着我们的品牌和价值观。” 然而&#xff0c;当前市面上的开源AI模型虽然技术先…

尝试使用tauri2+Django+React的项目

前言 使用Tauri2前端&#xff0c;本质是进程间的通信。并非前后端。 而想使用nw&#xff0c;先后端打包exe&#xff0c;再和前端打包成exe&#xff0c;并没有完成成功。 而笔者从Tauri中看到这种可能性。很有可能成功基于SeaORMMySQLTauri2ViteReact等的CRUD交互项目-CSDN博…

【JavaWeb学习Day27】

Tlias前端 员工管理 条件分页查询&#xff1a; 页面布局 搜索栏&#xff1a; <!-- 搜索栏 --><div class"container"><el-form :inline"true" :model"searchEmp" class"demo-form-inline"><el-form-item label…

Milvus WeightedRanker 对比 RRF 重排机制

省流:优先选择WeightedRanker 以rag为例,优先选择bm25全文检索,其次选择向量检索 Milvus混合搜索中的重排机制 Milvus通过hybrid_search() API启用混合搜索功能&#xff0c;结合复杂的重排策略来优化多个AnnSearchRequest实例的搜索结果。本主题涵盖了重排过程&#xff0c;…

PLY格式文件如何转换成3DTiles格式——使用GISBox软件实现高效转换

一、概述 在三维GIS和数字孪生领域&#xff0c;3DTiles格式已成为主流的数据格式之一。它由Cesium团队提出&#xff0c;专为大规模3D数据可视化设计&#xff0c;能够高效地加载和展示海量模型数据。而PLY格式则是一种常见的三维模型文件格式&#xff0c;主要用于存储点云数据或…

Junit在测试过程中的使用方式,具体使用在项目测试中的重点说明

JUnit 是一个广泛使用的 Java 单元测试框架,主要用于编写和运行可重复的测试。以下是 JUnit 在项目测试中的使用方式和重点说明: 1. 基本使用 场景:测试一个简单的 Java 类。 示例: import org.junit.Test; import static org.junit.Assert.*;public class CalculatorTe…