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)。理解如此庞大的数据集的生物学意义变得非常困难,尤其是在分析多个条件和比较的情况下。该软件包利用途径富集和蛋白-蛋白相互作用网络&…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
当下AI智能硬件方案浅谈
背景: 现在大模型出来以后,打破了常规的机械式的对话,人机对话变得更聪明一点。 对话用到的技术主要是实时音视频,简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术,开发自己的大模型。商用方案多见为字节、百…...