linux驱动开发-arm汇编基础
目录
写在前面
1、Cortex-A7 处理器有 9 种处理模式
2、Cortex-A 寄存器组
通用寄存器
1、汇编语法
2、Cortex-A7 常用汇编指令
2.1 处理器内部数据传输指令
2.1.1 传输数据操作类型
1、MOV指令
2、MRS指令
3、MSR指令
2.2、存储器访问指令
2.2.1 LDR指令
2.2.2 STR指令
2.3 压栈和出栈指令
2.4 跳转指令
2.4.1 B指令
2.4.2 BL指令
2.5算术运算指令
2.6 逻辑运算指令
相关好的博文:
写在前面
记录下学习arm汇编的一些知识点
1、Cortex-A7 处理器有 9 种处理模式

2、Cortex-A 寄存器组
ARM 架构提供了 16 个 32 位的通用寄存器(R0~R15)供软件使用,前 15 个(R0~R14)可以用作通用的数据存储, R15 是程序计数器 PC,用来保存将要执行的指令。 ARM 还提供了一个当前程序状态寄存器 CPSR 和一个备份程序状态寄存器 SPSR, SPSR 寄存器就是 CPSR 寄存器的备份。

通用寄存器
R0~R15 就是通用寄存器,通用寄存器可以分为以下三类:
①、 未备份寄存器,即 R0~R7。
②、 备份寄存器,即 R8~R14。
③、程序计数器 PC,即 R15。
1、未备份寄存器
未备份寄存器指的是 R0~R7 这 8 个寄存器,因为在所有的处理器模式下这 8 个寄存器都是同一个物理寄存器,在不同的模式下,这 8 个寄存器中的数据就会被破坏。所以这 8 个寄存器并没有被用作特殊用途。
2、备份寄存器
备份寄存器中的 R8~R12 这 5 个寄存器有两种物理寄存器,在快速中断模式下(FIQ)它们对应着 Rx_irq(x=8~12)物理寄存器,其他模式下对应着 Rx(8~12)物理寄存器。 FIQ 是快速中断模式,看名字就是知道这个中断模式要求快速执行! FIQ 模式下中断处理程序可以使用 R8~R12寄存器,因为 FIQ 模式下的 R8~R12 是独立的,因此中断处理程序可以不用执行保存和恢复中断现场的指令,从而加速中断的执行过程。备份寄存器 R13 一共有 8 个物理寄存器,其中一个是用户模式(User)和系统模式(Sys)共用的,剩下的 7 个分别对应 7 种不同的模式。 R13 也叫做 SP,用来做为栈指针。基本上每种模式都有一个自己的 R13 物理寄存器,应用程序会初始化 R13,使其指向该模式专用的栈地址,这就是常说的初始化 SP 指针。备份寄存器 R14 一共有 7 个物理寄存器,其中一个是用户模式(User)、系统模式(Sys)和超级监视模式(Hyp)所共有的,剩下的 6 个分别对应 6 种不同的模式。R14 也称为连接寄存器(LR),LR 寄存器在 ARM 中主要用作如下两种用途:
①、每种处理器模式使用 R14(LR)来存放当前子程序的返回地址,如果使用 BL 或者 BLX来调用子函数的话, R14(LR)被设置成该子函数的返回地址,在子函数中,将 R14(LR)中的值赋给R15(PC)即可完成子函数返回。
②、当异常发生以后,该异常模式对应的 R14寄存器被设置成该异常模式将要返回的地址,R14 也可以当作普通寄存器使用。
3、程序计数器 R15
程序计数器 R15 也叫做 PC, R15 保存着当前执行的指令地址值加 8 个字节,这是因为 ARM的流水线机制导致的。 ARM 处理器 3 级流水线:取指->译码->执行,这三级流水线循环执行,比如当前正在执行第一条指令的同时也对第二条指令进行译码,第三条指令也同时被取出存放在R15(PC)中。我们喜欢以当前正在执行的指令作为参考点,也就是以第一条指令为参考点,那么 R15(PC)中存放的就是第三条指令,换句话说就是 R15(PC)总是指向当前正在执行的指令地址再加上 2 条指令的地址。对于 32 位的 ARM 处理器,每条指令是 4 个字节
R15 (PC)值 = 当前执行的程序位置 + 8 个字节。
4、程序状态寄存器
所有的处理器模式都共用一个 CPSR 物理寄存器,因此 CPSR 可以在任何模式下被访问。CPSR 是当前程序状态寄存器,该寄存器包含了条件标志位、中断禁止位、当前处理器模式标志等一些状态位以及一些控制位。所有的处理器模式都共用一个 CPSR 必然会导致冲突,为此,除了 User 和 Sys 这两个模式以外,其他 7 个模式每个都配备了一个专用的物理状态寄存器,叫做 SPSR(备份程序状态寄存器),当特定的异常中断发生时, SPSR 寄存器用来保存当前程序状态寄存器(CPSR)的值,当异常退出以后可以用 SPSR 中保存的值来恢复 CPSR。
1、汇编语法
label: instruction @ comment
label 即标号,表示地址位置,有些指令前面可能会有标号,这样就可以通过标号得到这个指令的地址,标号也可以用来表示数据地址。 注意 label 后面的 “ :” ,任何以“ : ”结尾的标识符都会被识别为一个标号。
instruction 即指令 即汇编指令或者伪指令
@ 符号 , 表示后面的是注释,
comment 就是注释内容
注意:arm中的指令,伪指令,伪操作,寄存器名都可以全部使用大写,也可以全部使用小写,但是不能大小写混用。
开发者可以使用 .section 伪操作来定义一个段,汇编系统预定义了一些段名
.text 表示代码段
.data 表示初始化的数据段
.bss 表示未初始化的数据段
.rodata 表示只读数据段
用 .section 来定义一个段,每个段以段名开始,以下一个段名或者文件结尾结束·
.section .testsection @定义一个 testsection
汇编程序的默认入口标号是 _start ,通常在链接脚本中使用 ENTRY 来指明其他入口
.global_start
_start:ldr r0,=0x12 @r0=0x12
上面代码中 .global 是伪操作,表示 _start 是一个全局标号,常见伪操作包括
.byte 定义单字节数据 ,比如 .byte 0x12
.short 定义双字节数据,比如 .short 0x1234
.long 定义一个4字节数据 比如.long 0x12345678
.equ 赋值语句,格式是 .equ 变量名,表达式,比如 .equ num 0x12,表示 num=0x12
.align 数据字节对齐 比如:.align 4 表示4 字节对齐
.end 表示源文件结束
.global 定义一个全局符号,格式为 .global symbol ,比如 .global_start
GNU 汇编同时支持函数
函数名:
函数体
返回语句
GNU 汇编函数返回语句不是必须的,
/* 未定义中断 */
Undefined_Handler:
ldr r0, =Undefined_Handler
bx r0
其中 Undefined_Handler 是函数名,“ldr r0,=Undefined_Handler”是函数体,“bx r0”是函数返回语句,“bx”指令是返回指令,函数返回语句不是必须的。
2、Cortex-A7 常用汇编指令
2.1 处理器内部数据传输指令
2.1.1 传输数据操作类型
1、寄存器到寄存器
2、寄存器到特殊寄存器
3、立即数到寄存器
常用的数据传输指令: MOV MRS MSR
| 指令 | 目的 | 源 | 描述 |
| MOV | R0 | R1 | 将R1中数据传输到R0中 |
| MRS | R0 | CPSR | 将特殊寄存器CPSR中的数据复制到R0中 |
| MSR | CPSR | R1 | 将R1里面的数据复制到特殊寄存器CPSR中 |
1、MOV指令
MOV指令通常是将数据从一个寄存器拷贝到另一个寄存器中,或者将一个立即数传递到寄存器里面
MOV R0,R1 @寄存器R1中的数据传递给R0
MOV R0, #0x12 @将立即数0x12传递给R0寄存器
2、MRS指令
MRS指令用于将特殊寄存器的值复制给普通寄存器
MSR R0,CPSR @将CPSR中的数据复制到R0中
3、MSR指令
MSR指令和MRS指令相反,MSR 指令用来将普通寄存器的数据传递给特殊寄存器,也就是写特殊寄存器只能使用 MSR指令
MSR CPSR,R0 @将R0中的数据复制到CPSR中
2.2、存储器访问指令
arm 不能直接访问存储器,也就是需要将存储器中的数据读到寄存器中,常用的存储器访问指令主要有 LDR 和 STR
| 指令 | 描述 |
| LDR Rd, [Rn , #offset] | 从存储器Rn+osset的位置读取数据存放到Rd中 |
| STR Rd, [Rn,#offset] | 将 Rd 中的数据写入到存储器中的 Rn+offset 位置 |
2.2.1 LDR指令
LDR是将数据从存储器加载到寄存器 Rx中,LDR 也可以将立即数加载到寄存器 Rx中,LDR 加载立即数的时候要用 = ,不能使用 # 来描述立即数 。嵌入式开发中,LDR 最常用的就是读取 CPU 的寄存器值,加入有个寄存器 REG0 ,其地址为 0x81000000 ,我们要读取这个寄存器中数据,示例代码如下:
LDR R0, =0x81000000 @将寄存器地址加载到 R0 中,
LDR R1,[R0] @读取地址0x81000000 中的数据到 R1 寄存器中
没有用到 offset ,则代表 offset 值为0
2.2.2 STR指令
LDR指令是从存储器读取数据,STR 指令是将数据写入到存储器中
LDR R0, =0x81000000
LDR R1, =0x81000008
STR R1, [R0] @将R1中的值写入到 R0 中保存的地址中
LDR 和 STR 都是按照字进行读取和写入的,也就是操作的是 32位的数据,如果要按照字节、半字操作的话,可以在 LDR 指令后加上 B或者 H ,字节操作的指令就是 LDRB 和 STRB,按半字进行操作的指令就是 LDRH 和 STRH
2.3 压栈和出栈指令
会在 A 函数中调用 B 函数,当 B 函数执行完以后再回到 A 函数继续执行。要想再跳回 A 函数以后代码能够接着正常运行,那就必须在跳到 B 函数之前将当前处理器状态保存起来(就是保存 R0~R15 这些寄存器值),当 B 函数执行完成以后再用前面保存的寄存器值恢复R0~R15 即可。保存 R0~R15 寄存器的操作就叫做现场保护,恢复 R0~R15 寄存器的操作就叫做恢复现场。在进行现场保护的时候需要进行压栈(入栈)操作,恢复现场就要进行出栈操作。压栈的指令为 PUSH,出栈的指令为 POP, PUSH 和 POP 是一种多存储和多加载指令,即可以一次操作多个寄存器数据,他们利用当前的栈指针 SP 来生成地址。
| 指令 | 描述 |
| PUSH <reg list> | 将寄存器列表存入栈中 |
| POP <reg list> | 从栈中恢复寄存器列表 |
假如我们现在要将 R0~R3 和 R12 这 5 个寄存器压栈,当前的 SP 指针指向 0X80000000,处理器的堆栈是向下增长的,使用的汇编代码如下:
PUSH {R0~R3,R12} @将R0~R3和R12 压栈

PUSH {LR} @将 LR 进行压栈

POP {LR} @先恢复 LR
POP {R0~R3,R12} @在恢复 R0~R3,R12
2.4 跳转指令
跳转操作通常可以使用 跳转指令 B、BL、BX;也可以直接往 PC 寄存器中写值,下面详细介绍一下汇编指令
| 指令 | 描述 |
| B <label> | 跳转到label ,如果跳转了超过 +、- 2KB ,可以指定 B.W <label>指令使用32位版本的跳转指令 |
| BX <Rm> | 间接跳转,跳转到存放在 Rm 中的地址处,并切换指令集 |
| BL <label> | 跳转到标号位置,并将返回地址保存在 LR 中 |
| BLX <Rm> | 结合 BX 和 BL的特点,跳转到 Rm 指定的地址,并将返回地址保存到 LR 中,切换指令集 |
2.4.1 B指令
B指令会将 PC 寄存器的值设置为跳转目标地址,但是不会再返回原来的执行处
_start:
dr sp,=0X80200000 @设置栈指针
b main @跳转到 main 函数
在汇编中初始化C运行环境,然后跳转到C语言的main函数处
2.4.2 BL指令
BL指令相较于 B指令,在跳转之前会在寄存器 LR(R14)中保存当前PC寄存器的值,所以可以通过 LR 寄存器恢复现场
push {r0, r1} @保存 r0,r1
cps #0x13 @进入 SVC 模式,允许其他中断再次进去
bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中
cps #0x12 @进入 IRQ 模式
pop {r0, r1}
str r0, [r1, #0X10] @中断执行完成,写 EOIR
2.5算术运算指令

2.6 逻辑运算指令

相关好的博文:
GNU风格 汇编语法总结_gnu汇编语法-CSDN博客
https://www.cnblogs.com/zhumengke/articles/10643032.html
相关文章:
linux驱动开发-arm汇编基础
目录 写在前面 1、Cortex-A7 处理器有 9 种处理模式 2、Cortex-A 寄存器组 通用寄存器 1、汇编语法 2、Cortex-A7 常用汇编指令 2.1 处理器内部数据传输指令 2.1.1 传输数据操作类型 1、MOV指令 2、MRS指令 3、MSR指令 2.2、存储器访问指令 2.2.1 LDR指令 2.2.2 …...
【HarmonyOS】鸿蒙头像上传-(编辑个人信息页- 头像上传)+实时数据更新
#效果图 #思路 ##步骤: ###一、利用picker api选择1张图片 实例化选择器参数(使用new PhotoSelectOptions())实例化图片选择器 (使用newPhotoViewPicker() )调用图片选择器的select方法传入选择器参数完成图片选取获得结果 利用picker api选择1张图片 async sele…...
[数据集][目标检测]无人机识别检测数据集VOC+YOLO格式6986张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):6986 标注数量(xml文件个数):6986 标注数量(txt文件个数):6986 标注…...
基于SSM的二手交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的二手交易管理系统1拥有两种角色 管理员:商品管理、订单管理、充值管理、用户管理等用户:发布商品、查看闲置、充值账户、查看所有订单、发布求购信息、修…...
linux-centos 设置系统时间
CentOS 系统提供了多种方式来设置和管理时间,包括手动设置时间和使用网络时间协议 (NTP) 自动同步时间。以下是几种常见的方法: 手动设置时间 使用date命令临时设置时间: 如果你只需要临时设置时间,可以使用 date 命令࿱…...
【Linux基础】冯诺依曼体系结构操作系统的理解
目录 前言一,冯诺依曼体系1. 为什么有内存结构?2. 对硬件中数据流动的再理解 二,操作系统(Operator System)1. 概念2. 操作系统结构的层状划分3. 操作系统对硬件管理的理解4. 用户与操作系统的关系的理解5. 系统调用和库函数的关系6. 为什么要有操作系统…...
算法题解:斐波那契数列(C语言)
斐波那契数列 斐波那契数列是一个经典的数学序列,其中每一项的值是前两项的和。数列的前两项通常定义为0和1,即: F(0) 0 F(1) 1 F(n) F(n-1) F(n-2) (n ≥ 2)输入一个正整数n,求斐波那契数列的第n项。 样例 假设输入 n …...
SSM 框架 个人使用习惯 详细
SpringMVC主要是controller、service、dao(mapper)层交互 controller:处理数据请求的接口 service:处理请求的数据 dao(mapper):对数据进行持久化 下面我将对controller和service.impl进行讲…...
[羊城杯 2020]Blackcat1
知识点:数组加密绕过 进入页面熟悉的web三部曲(url地址,web源代码,web目录扫描) url地址没有什么东西去看看源代码. 这有一个mp3文件点一下看看. 在最后面发现了 PHP源码. if(empty($_POST[Black-Cat-Sheriff]) || em…...
腾讯云Ubuntu系统安装宝塔,配置Java环境,运行spring boot项目
致谢 本次学习宝塔部署spring boot项目,参考如下资料 https://www.cnblogs.com/daen/p/15997872.html 系统安装宝塔 直接用的腾讯云云服务器面板上的登录,你可以换成 xshell 进入宝塔官网: https://www.bt.cn/new/download.html 我们采…...
双亲委派机制知识点
类加载器 双亲委派模型 为什么采用双亲委派模型 打破双亲委派机制的场景 Tomcat 打破双亲委派机制:目的是可以加载不同版本的jar包 实现类隔离:在Tomcat中,每个Web应用使用独立的类加载器加载类文件,这样做的好处在于,当在同一T…...
vue part 11
vuex的模块化与namespace 115_尚硅谷Vue技术_vuex模块化namespace_1_哔哩哔哩_bilibili 116_尚硅谷Vue技术_vuex模块化namespace_2_哔哩哔哩_bilibili vue-router路由 很常见的很重要的应用:Ajax请求,将响应的数据替换掉原先的代码从而实现不跳转页面…...
【QT】常用类
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:QT 目录 👉🏻QMediaPlayer👉🏻QMediaPlaylistsetPlaybackMode 👉🏻QDir👉…...
从index_put出发全面学习cuda和pytorch技术
一 前言 深感目前对于cuda和pytorch所涉及知识的广度和深度,但一时又不知道该如何去学习,经过多日的考虑,还是决定管中窥豹,从一个算子出发,抽丝剥茧,慢慢学习,把学习中碰到的问题都记录下来,希望可以坚持下去。 二 函数功能描述 【torch算子】torch.index_put和tor…...
浅谈住房城乡建设部科技创新平台布局重点方向
最近住房建设部组织开展住房城乡建设部科技创新平台(以下简称部科技创新平台)申报工作。详细内容见住房城乡建设部科技创新平台开始申报了 (qq.com)。在这里有4大方向共15个课题。内容见下图: 虽然我是做技术的,但是如何体现创新还…...
调用 write()函数后,如何知道数据是否已经写入磁盘?
在 Linux 中调用 write() 函数后,可以通过以下几种方式来确定数据是否已经写入磁盘: 一、使用同步函数 1. fsync() 函数: - 这个函数会强制将与文件描述符相关的所有修改过的内核缓冲区写入磁盘,并等待直到磁盘 I/O 操作完…...
策略路由与路由策略的区别
🐣个人主页 可惜已不在 🐤这篇在这个专栏 华为_可惜已不在的博客-CSDN博客 🐥有用的话就留下一个三连吧😼 目录 一、主体不同 二、方式不同 三、规则不同 四、定义和基本概念 一、主体不同 1、路由策略:是为了改…...
从底层原理上理解ClickHouse 中的稀疏索引
稀疏索引(Sparse Indexes)是 ClickHouse 中一个重要的加速查询机制。与传统数据库使用的 B-Tree 或哈希索引不同,ClickHouse 的稀疏索引并不是为每一行数据构建索引,而是为数据存储的块或部分数据生成索引。这种索引的核心思想是通…...
xtu oj 锐角三角形
锐角三角形 题目描述 n条边,任选3条边,能组成多少个锐角三角形(选的边不同就认为是不同的三角形)? 输入 第一个是一个整数T(1≤T≤1000),表示样例的个数。 每个样例占2行,第一行是一…...
MATLAB系列04:循环结构
MATLAB系列04:循环结构 4. 循环结构4.1 while循环4.2 for循环4.2.1 运算的细节4.2.2 break语句和continue语句4.2.3 嵌套循环 4.3 逻辑数组和向量化4.3.1 逻辑数组的重要性4.3.2 用 if/else 结构和逻辑数组创建等式 4.4 总结 4. 循环结构 循环(loop)是一种 MATLAB …...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...
python打卡第47天
昨天代码中注意力热图的部分顺移至今天 知识点回顾: 热力图 作业:对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图,展示模…...
背包问题双雄:01 背包与完全背包详解(Java 实现)
一、背包问题概述 背包问题是动态规划领域的经典问题,其核心在于如何在有限容量的背包中选择物品,使得总价值最大化。根据物品选择规则的不同,主要分为两类: 01 背包:每件物品最多选 1 次(选或不选&#…...
