STM32学习【4】ARM汇编(够用)
目录
- ARM汇编语言基础
- 写在前面
- 1. ARM汇编的分类
- 2. 关于指令集
- 指令集切换
- Thumb2指令集
- 统一汇编语言(UAL)
- 常用汇编指令
- 3. 汇编格式
- 立即数与伪指令
- 4. 操作内存的汇编指令
- LDR:从内存加载数据到CPU寄存器
- STR:将数据从寄存器存储到内存
- LDM:从存储器中加载多个数据到寄存器组
- 满增、满减, 空增,空减
- 5. 数据处理汇编指令
- 加法指令ADD:
- 减法指令SUB:
- 位操作:
- 比较:
- 6.跳转指令
ARM汇编语言基础
对于学习汇编,我有话说,哈,我们实际工作中用到的并不多,我们学会常用的,遇见不会的直接大模型问就可以了,通过汇编,我们可以体会到数据底层的流动规律,写代码自然就会通透,更近一步,我们要彻底学会RTOS,底层的知识也是必不可少的。
写在前面
在CPU的世界里,一切外设都被抽象为寄存器或带有地址的内存数据。CPU只关心其内部的16个寄存器以及内存数据,外设寄存器虽然物理上与内存不同,但在CPU眼中并无区别,唯一的差异在于地址空间。
1. ARM汇编的分类
ARM汇编语言大致可以分为以下几类:
- 内存读写:用于访问内存数据。
- 运算类:执行加法、减法、逻辑运算等。
- 跳转/分支:实现程序流程控制。
- 比较:类似于高级语言中的
if语句。
这些指令组合成指令集,构成了ARM汇编语言的核心。
2. 关于指令集
ARM公司发布了两类主要的指令集:
- ARM指令集:32位指令,每条指令占用32位。优点是执行效率高,但占用空间较大。
- Thumb指令集:16位指令,每条指令占用16位。优点是节省空间,但执行效率稍低。
在实际应用中:
- 如果需要节省空间,优先使用Thumb指令集。
- 如果需要高效执行,优先使用ARM指令集。
一个CPU既可以运行Thumb指令,也可以运行ARM指令。如何区分当前指令是Thumb还是ARM指令呢?程序状态寄存器(CPSR)中有一位名为“T”,当T=1时,表示当前运行的是Thumb指令。
指令集切换
指令集的切换通过设置PC寄存器的最低位(BIT0)来实现:
- 调用函数A(Thumb指令)时,将PC寄存器的最低位设置为1,即
PC = 函数A地址 + (1<<0)。 - 调用函数B(ARM指令)时,将PC寄存器的最低位设置为0,即
PC = 函数B地址。
这种切换方式是通过跳转指令(如B或BL)实现的,目标地址的最低位决定了目标函数的指令集模式。在实际开发中,通常使用链接器或编译器工具来管理指令集切换,而不是手动设置PC寄存器的最低位。
Thumb2指令集
为了简化指令集切换,ARM公司引入了Thumb2指令集。Thumb2指令集支持16位和32位指令混合使用,允许在同一个指令集中无缝切换指令长度,而无需显式切换指令集。编译器通常会自动选择最优的指令长度,以平衡代码大小和执行效率。
统一汇编语言(UAL)
为了简化开发,ARM公司推出了统一汇编语言(UAL)。开发者无需区分ARM、Thumb或Thumb2指令集,只需在程序中使用CODE32、CODE16或THUMB指令来指定代码段的指令集类型。
常用汇编指令
在日常工作中,常用的ARM汇编指令包括:
- 数据传输:
MOV、LDR、STR、LDM、STM - 逻辑运算:
AND、OR - 算术运算:
ADD、SUB - 跳转:
B、BL - 数据定义:
DCD - 地址操作:
ADR、LDR - 比较:
CMP
3. 汇编格式
以“数据处理”指令为例,UAL汇编格式为:
Operation{cond}{S} Rd, Rn, Operand2
- Operation:表示各类汇编指令,如
ADD、MOV。 - cond:条件码,指定指令执行的条件。例如,
EQ(相等)、NE(不相等)、CS(无符号大于等于)、CC(无符号小于)等。条件码可以应用于大多数指令,但某些指令(如LDM和STM)不支持条件码。 - S:是否修改程序状态寄存器(CPSR)。如果指令带有
S后缀,执行结果会影响CPSR中的条件标志。 - Rd:目标寄存器,用于存储运算结果。
- Rn:第一个源操作数。
- Operand2:第二个操作数。
立即数与伪指令
在16位指令中,由于指令长度限制,立即数(直接给出的数值)的范围有限。例如,MOV R0, #VAL指令中,VAL不可能占用全部16位,毕竟MOV ,R0也需要一些位来表示其含义。为此,ARM提供了伪指令,让编译器自动处理复杂的立即数转换。
例如:
MOV R0, #0x12345678 ; 伪指令,编译器会自动将其拆分为多条指令实现
在ARM指令集中,32位指令可以支持更大的立即数范围,但仍有限制。伪指令由编译器自动转换为多条指令,以实现复杂的立即数加载。
4. 操作内存的汇编指令
LDR:从内存加载数据到CPU寄存器
LDR指令用于从内存中加载数据到CPU寄存器。如果不指定数据类型,默认为32位数据。LDR支持多种寻址方式,包括偏移寻址、基址寻址和后索引寻址等,但是实际我们工作中用的的都是相对比较简单的。
例如:
LDR R0, [R1] ; 将R1指向的内存地址中的数据加载到R0
LDR R0, [R1, #4] ; 将R1+4地址中的数据加载到R0
LDRB R0, [R1] ; 加载8位数据到R0
LDRH R0, [R1] ; 加载16位数据到R0
STR:将数据从寄存器存储到内存
STR指令用于将数据从寄存器存储到内存。STR也支持多种寻址方式。
例如:
MOV R0, #0x20000
MOV R1, #0x10
MOV R2, #0x12
STR R2, [R0] ; 将R2的值存储到R0指向的地址
STR R2, [R0, #4] ; 将R2的值存储到R0+4地址
STR R2, [R0, #8]! ; 将R2的值存储到R0+8地址,并将R0更新为R0+8
STR R2, [R0, R1] ; 将R2的值存储到R0+R1地址
STR R2, [R0, R1, LSL #4] ; 将R2的值存储到R0+(R1<<4)地址
STR R2, [R0], #0x20 ; 将R2的值存储到R0地址,并将R0更新为R0+0x20
STRB R2, [R0] ; 存储8位数据到R0指向的地址
LDM:从存储器中加载多个数据到寄存器组
LDM指令用于批量加载多个寄存器,格式为:
LDM{addr_mode}{cond} Rn{!}, reglist{^}
- addr_mode:
IA:Increment After,每次传输后增加基地址(默认,可省略)。IB:Increment Before,每次传输前增加基地址(仅ARM指令可用)。DA:Decrement After,每次传输后减少基地址(仅ARM指令可用)。DB:Decrement Before,每次传输前减少基地址。
- !:表示修改后的基地址会写回Rn寄存器。如果没有
!,则Rn保持原值。 - ^:表示会影响程序状态寄存器(CPSR),通常在异常处理中使用。
要注意:低位置寄存机对应低地址,比如R0寄存器属于最低的位置寄存器,R15是最高的寄存器。
有个问题,为什么需要这么多的addr_mode?
比如我们往栈中写数据的时候,有两种情况
1.SP寄存器所指的地址有数据(满栈),这个时候我们需要先调整地址再写数据。
2.SP寄存器所指的地址没有数据(空栈),这种情况是先写数据再调整地址。
很明显我们需要不同的行为的需求,自然也就要有了多种addr_mode.
满增、满减, 空增,空减
根据栈指针指向,可分为满(Full)/空(Empty):
满SP指向最后一个入栈的数据,需要先修改SP再入栈
空SP指向下一个空位置,先入栈再修改SP
根据压栈时SP的增长方向,可分为增/减:
增(Ascending):SP变大
减(Descending):SP变小
组合后,就有4种方式: 满增、满减, 空增,空减。
常用的“满减”: 入栈时用STMDB,也可以用STMFD,作用一样;注意是先减地址后存内容
出栈时用LDMIA,也可以用LDMFD,作用一样。先读内容后加地址

下面是几个例子,加黑的内容是汇编指令,方框内为内存结果,

5. 数据处理汇编指令
数据处理汇编指令有很多,我们并不需要全部掌握,只需要注意关键的几条即可。
加法指令ADD:
ADD R1, R2, R3 ; R1 = R2 + R3ADD R1, R2, #0x12 ; R1 = R2 + 0x12
减法指令SUB:
SUB R1, R2, R3 ; R1 = R2 - R3SUB R1, R2, #0x12 ; R1 = R2 - 0x12
位操作:
; VisUAL里不支持(1<<4)这样的写法,写成:0x10AND R1, R2, #(1<<4) ; 位与,R1 = R2 & (1<<4)AND R1, R2, R3 ; 位与,R1 = R2 & R3BIC R1, R2, #(1<<4) ; 清除某位,R1 = R2 & ~(1<<4)BIC R1, R2, R3 ; 清除某位,R1 = R2 & ~R3ORR R1, R2, R3
比较:
关于比较要说明一下,CMP的对比结果会储存在状态寄存器里面,下面的语句会根据状态寄存器里面的值决定是否执行,比如MOVEQ,相等时才执行
CMP R0, R1 ; 比较R0-R1的结果
CMP R0, #0x12 ; 比较R0-0x12的结果
TST R0, R1 ; 测试 R0 & R1的结果
TST R0, #(1<<4) ; 测试 R0 & (1<<4)的结果
6.跳转指令
C程序中,函数A调用函数B的实质是什么?
void A()
{
int a = 10;
B(a);
printf(“ok”);
}
实质是:跳转去执行函数B的代码,函数B执行完后,还要回到函数A继续执行后面的代码。
对应的汇编指令就是跳转指令,要主要,凡事有正反,跳走了也要知道怎么跳回来,所以要保存返回地址。

相关文章:
STM32学习【4】ARM汇编(够用)
目录 ARM汇编语言基础写在前面 1. ARM汇编的分类2. 关于指令集指令集切换Thumb2指令集统一汇编语言(UAL)常用汇编指令 3. 汇编格式立即数与伪指令 4. 操作内存的汇编指令LDR:从内存加载数据到CPU寄存器STR:将数据从寄存器存储到内…...
Linux驱动开发实战(一):LED控制驱动详解
Linux驱动开发野火实战(一):LED控制驱动详解 文章目录 Linux驱动开发野火实战(一):LED控制驱动详解引言一、基础知识1.1 什么是字符设备驱动1.2 重要的数据结构read 函数write 函数open 函数release 函数 二…...
windows下安装pyenv+virtualenv+virtualenvwrapper
1、下载pyenv 进入git官网,打包下载zip到本地 2、解压到安装目录 解压下载好的pyenv-win-master.zip到自己的安装目录,如D:\Program Files 3、配置环境变量 右击桌面 此电脑 --> 属性 --> 高端系统设置 --> 环境变量 --> 新建系统变量…...
Cherno 游戏引擎笔记(91~111)
好久不见! 个人库的地址:(GitHub - JJJJJJJustin/Nut: The game_engine which learned from Cherno),可以看到我及时更新的结果。 -------------------------------Saving & Loading scene-----------------------…...
0x02 js、Vue、Ajax
文章目录 js核心概念js脚本引入html的方式基础语法事件监听 Vuevue简介v-forv-bindv-if&v-showv-model&v-on Ajax js 核心概念 JavaScript:是一门跨平台、面向对象的脚本语言,用来控制网页行为实现交互效果,由ECMAScript、BOM、DOM…...
Windows 11【1001问】删除Win11左下角小组件的6种方法
在Windows 11中,左下角的小组件功能虽然提供了天气、新闻等实用信息,但对于一些用户来说可能显得多余或干扰视线。因此,微软提供了多种方式让用户能够自定义是否显示这些小组件。以下是 6 种常见的设置方法来隐藏或关闭Windows 11左下角的小组…...
【动手学深度学习】基于Python动手实现线性神经网络
深度学习入门:基于Python动手实现线性回归 1,走进深度学习2,配置说明3,线性神经网络4,线性回归从0开始实现4.1,导入相关库4.2,生成数据4.3,读取数据集4.4,初始化模型参数…...
leetcode 912. 排序数组
912. 排序数组 912. 排序数组 题目 给你一个整数数组 nums,请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。 示例 1: 输入:nums [5,2,3,1…...
【芯片设计】NPU芯片前端设计工程师面试记录·20250227
应聘公司 某NPU/CPU方向芯片设计公司。 小声吐槽两句,前面我问了hr需不需要带简历,hr不用公司给打好了,然后我就没带空手去的。结果hr小姐姐去开会了,手机静音( Ĭ ^ Ĭ )面试官、我、另外的hr小姐姐都联系不上,结果就变成了两个面试官和我一共三个人在会议室里一人拿出…...
BUU40 [CSCCTF 2019 Qual]FlaskLight1【SSTI】
模板: {{.__class__.__base__.__subclasses__()[80].__init__.__globals__[__builtins__].eval("__import__(os).popen(type flag.txt).read()")}} 是个空字符串,.__class__代表这个空字符串的类是什么(这里是单引号双引号都行&a…...
WiFi IEEE 802.11协议精读:IEEE 802.11-2007,6,MAC service definition MAC服务定义
继续精读IEEE 802.11-2007 6,MAC service definition MAC服务定义 6.1 MAC服务概述 6.1.1 数据服务 此服务为对等逻辑链路控制(LLC)实体提供交换MAC服务数据单元(MSDU)的能力。为支持此服务,本地媒体访…...
2025学年安徽省职业院校技能大赛 “信息安全管理与评估”赛项 比赛样题任务书
2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(五) 第一部分:网络平台搭建与设备安全防护任务书第二部分:网络安全事件响应、数字取证调查、应用程序安全任务书任务1 :内存取证&…...
VAE变分自编码器的初步理解
VAE的结构和原理 VAE由两部分组成: 编码器(Encoder): 编码器负责将输入数据(例如图像)压缩成一个潜在空间(latent space)的表示。这个潜在空间不是一个固定的值,而是一个…...
2025 最新版鸿蒙 HarmonyOS 开发工具安装使用指南
为保证 DevEco Studio 正常运行,建议电脑配置满足如下要求: Windows 系统 操作系统:Windows10 64 位、Windows11 64 位内存:16GB 及以上硬盘:100GB 及以上分辨率:1280*800 像素及以上 macOS 系统 操作系统…...
Rider 安装包 绿色版 Win/Mac/Linux 适合.NET和游戏开发者使用 2025全栈开发终极指南:从零配置到企业级实战
下载链接: https://pan.baidu.com/s/1cfkJf6Zgxc1XfYrVpwtHkA?pwd1234 导语:JetBrains Rider以跨平台支持率100%、深度.NET集成和智能代码分析能力,成为2025年全栈开发者的首选工具。本文涵盖环境配置、核心功能、框架集成、性能调优、团队…...
Python常见面试题的详解24
1. 如何对关键词触发模块进行测试 要点 功能测试:验证正常关键词触发、边界情况及大小写敏感性,确保模块按预期响应不同输入。 性能测试:关注响应时间和并发处理能力,保证模块在不同负载下的性能表现。 兼容性测试:测…...
手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人
手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中,使用蓝牙电话拦截手机通话的声音,并对数据加工,这个功能出来也有一段时间了。前段时间有试用的用户咨询说:有没有办法在手机上ÿ…...
RabbitMQ操作实战
1.RabbitMQ安装 RabbitMQ Windows 安装、配置、使用 - 小白教程-腾讯云开发者社区-腾讯云下载erlang:http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安装RabbitMQ及延时消息插件rabbitmq_delayed_message_exch…...
IDEA 2024.1 最新永久可用(亲测有效)
今年idea发布了2024.1版本,这个版本带来了一系列令人兴奋的新功能和改进。最引人注目的是集成了更先进的 AI 助手,它现在能够提供更复杂的代码辅助功能,如代码自动补全、智能代码审查等,极大地提升了开发效率。此外,用…...
【R包】pathlinkR转录组数据分析和可视化利器
介绍 通常情况下,基因表达研究如微阵列和RNA-Seq会产生数百到数千个差异表达基因(deg)。理解如此庞大的数据集的生物学意义变得非常困难,尤其是在分析多个条件和比较的情况下。该软件包利用途径富集和蛋白-蛋白相互作用网络&…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
