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)。理解如此庞大的数据集的生物学意义变得非常困难,尤其是在分析多个条件和比较的情况下。该软件包利用途径富集和蛋白-蛋白相互作用网络&…...
Unity Il2CppDumper原理与实战:解析元数据与二进制对齐
1. 这不是“破解工具”,而是Unity开发者该懂的二进制真相课 你刚在Unity Asset Store下载了一个功能惊艳的插件,却在打包iOS后发现部分逻辑失效;或者接手一个没有源码的旧项目,只有一堆 .dll 和 .so 文件,连主入口…...
从测速到配置:一套完整的cFosSpeed网络加速保姆级教程(适用于小白)
从零开始掌握cFosSpeed:网络加速全流程实战指南对于经常进行在线游戏、视频会议或大文件传输的用户来说,网络延迟和带宽利用率低下往往是影响体验的关键痛点。cFosSpeed作为一款专业的网络流量优化工具,能够显著改善这些问题,但许…...
AI大模型应用开发全攻略:从入门到精通,掌握LLM、RAG、Agent核心技能!“
本文全面介绍了AI大模型应用开发的核心技术和实践。从大模型API交互基础,到关键参数Messages和Tools的作用,深入解析了RAG、ReAct、Agent等应用范式。文章还探讨了Fine-tuning微调和Prompt提示词工程的重要性,强调工程实践与业务需求相结合。…...
千亿镁合金产业集群正在成形:成都、抚州、池州的新版图
一个新赛道的地理坐标 如果要在中国地图上标注一条正在成形的新兴产业集群走廊,高强镁合金这条线,值得被认真画出来。 成都龙泉驿——江西抚州临川——安徽池州高新区,三个坐标,三条生产线,一家公司,两年内…...
炉石传说自动对战助手:5分钟上手,彻底解放双手的终极指南
炉石传说自动对战助手:5分钟上手,彻底解放双手的终极指南 【免费下载链接】Hearthstone-Script Hearthstone script(炉石传说脚本) 项目地址: https://gitcode.com/gh_mirrors/he/Hearthstone-Script 还在为每天重复的炉石…...
CANoe诊断测试没CDD文件怎么办?手把手教你用Fault Memory窗口和CAPL脚本读取解析DTC故障码
CANoe诊断测试无CDD文件的实战解决方案:从Fault Memory到CAPL脚本全解析当CDD文件缺失或定义不清晰时,诊断测试工程师常常陷入困境。本文将深入探讨如何利用Fault Memory窗口的基础功能,并通过CAPL脚本实现更灵活、更强大的故障码读取与解析方…...
LVGL多页面开发避坑:用内部Timer替代轮询,解决页面切换时的内存踩踏问题
LVGL多页面开发中的内存安全实践:用Timer机制替代轮询的工程解决方案 在嵌入式UI开发中,LVGL因其轻量级和跨平台特性成为热门选择。但当项目复杂度提升到多页面交互时,开发者往往会遇到一个棘手问题:如何在频繁切换页面的同时保证…...
百度深度学习研究院的“叛将“,带着一颗芯片改变了中国智能驾驶——地平线余凯,从ImageNet冠军到征程出货1000万
大家好,我是写代码的篮球球痴。这篇文章跟我自己有点关系——我开的是理想汽车。理想的智驾系统 AD Pro,搭载的就是地平线征程 5 芯片。2026 年 1 月理想 AD Pro 4.0 推送,基于单颗征程 6M 实现了城市 NOA——这是行业里第一个用单颗 128TOPS…...
如何用WaveTools终极优化《鸣潮》游戏性能:从卡顿到丝滑的完整指南
如何用WaveTools终极优化《鸣潮》游戏性能:从卡顿到丝滑的完整指南 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 如果你正在玩《鸣潮》却频繁遭遇帧率波动、画面卡顿或操作延迟,那…...
3分钟告别英文恐惧:Android Studio中文界面轻松切换指南
3分钟告别英文恐惧:Android Studio中文界面轻松切换指南 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本) 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 你是否曾经因…...
