【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令
文章目录
- 指令格式(重点)
- 1. 立即数
- 2. 寄存器位移
- 一、数据传送指令
- 1. MOV指令
- 2. MVN指令
- 3. LDR指令
- 二、数据计算指令
- 1. ADD指令
- 1. SUB指令
- 1. MUL指令
- 三、位运算指令
- 1. AND指令
- 2. ORR指令
- 3. EOR指令
- 4. BIC指令
- 四、比较指令
- 五、跳转指令
- 1. B/BL指令
- 2. ldr指令
- 练习
- 六、内存访问指令
- 1. 单内存访问指令
- 练习
- 2. 多内存访问指令
- 示例
- 3. 栈操作指令
- 示例
- 七、CPSR/SPSR操作指令
- 练习
- 八、ARM指令流水线分析及伪指令
- 1. 最佳流水线
- 2. 内存访问指令流水线
- 3. 分支流水线
- 4. ARM伪指令、汇编与C混合编程、Volatile关键字
- (1)LDR R0,=0x12345678分析
- (2)LDR R0,=Label 分析
- (3)LDR R0,Label
- (4)ADR R0,Label分析
- (5)如何判别代码在实际内存中运行的地址?
指令格式(重点)

1. 立即数
一个常数,该常数必须对应8位位图,即一个8位的常数通过,循环右移偶数位得到该数,该数
数为合法立即数。
在指令中表示方法:#数字,例如:#100
快速判定是否是合法立即数:
- 首先将这个数转换为32bit的16进制形式,例如
218=0xDA=0x000000DA - 除零外,仅有一位数为合法立即数
- 除零外,仅有二位数,并且相邻(包括首尾,如
0x1000000A)的为合法立即数。 - 除零外,仅有三位数,并且相邻(包括中间有0相间,例如
0x10800000,包括首尾相邻
如:0x14000003),这三位数中,最高位取值仅能为1、2、3,最低位取值仅能为4、8、C
中间位0x0~0xF。 这种组合的为合法立即数。
2. 寄存器位移
将寄存器值读取之后,进行移位运算后,作为操作数2参与运算。支持的移位方式如下:
LSL(Logical shift Left)逻辑右移LSR(Logical shift Right)逻辑左移ASR(Arithmetic shift Right)算术右移
r0,lsr #4 表示r0 >>4
r0,lsr r1 表示r0 >>r1
#3,LsL #4 错误,只能是寄存器移位,不能是立即数移位
一、数据传送指令
1. MOV指令
格式:mov 目标寄存器,操作数2
功能:将操作数2的值赋值给目标寄存器

2. MVN指令
格式:mvn 目标寄存器,操作数2
功能:将操作2取反的值给目标寄存器

3. LDR指令
格式: LDR 目标寄存器,= 数据
功能: 完成任意的数据传送到目标寄存器
注意: 数据前面不能加#,因为此时数据不按立即数来处理

二、数据计算指令
1. ADD指令
格式: add 目标寄存器,操作数1,操作数2
功能: 将操作数1加上操作数2的结果给目标寄存器

1. SUB指令
格式: sub 目标寄存器,操作数1,操作数2
功能: 将操作数1减去操作数2的结果给目标寄存器

1. MUL指令
格式: mul 目标寄存器,操作1,操作2
功能: 将操作数1乘以操作数2的结果存放在目标寄存器
注意:操作数1和操作2必须都是寄存器,并且操作1的寄存器编号不能和目标寄存器一样

三、位运算指令
1. AND指令
格式: and 目标寄存器,操作数1,操作数2
功能: 将操作数1按位与操作数2的结果存放在目标寄存器

2. ORR指令
格式: orr 目标寄存器,操作数1,操作数2
功能: 将操作1按位或操作2的结果存放在目标寄存器
3. EOR指令
格式: eor 目标寄存器,操作1,操作2
功能: 将操作数1按位异或操作数2的结果存放在目标寄存器

4. BIC指令
格式: bic 目标寄存器,操作1,操作2
功能: 将操作数1按位与操作数2取反的结果存放在目标寄存器
目标寄存器 = 操作数1 & ~操作数2

四、比较指令
格式: cmp 寄存器,操作数2
等于寄存器减去操作数2
功能: 将寄存器的值与操作2比较,比较的结果会自动影响CPSR的NZCV

答案

五、跳转指令
1. B/BL指令
格式: B/BL 标签
功能: 跳到一个指定的标签,BL 跳转之前,将跳转前的PC的值保存在LR,跳转范围+/- 32M

NZCV 标志位
| 标志位 | 含义 |
|---|---|
| N (Negative) | 结果为负数(Rn < Rm) |
| Z (Zero) | 结果为 0(Rn == Rm) |
| C (Carry) | 发生借位(无符号比较时 Rn < Rm) |
| V (Overflow) | 溢出(有符号计算超出范围) |
比较指令 + B 条件跳转
| 指令 | 条件 | 说明 |
|---|---|---|
BEQ label | Z == 1 | 相等(Rn == Rm)时跳转 |
BNE label | Z == 0 | 不相等(Rn ≠ Rm)时跳转 |
BGT label | Z == 0 且 N == V | 大于(Rn > Rm,有符号)时跳转 |
BGE label | N == V | 大于等于(Rn ≥ Rm,有符号)时跳转 |
BLT label | N ≠ V | 小于(Rn < Rm,有符号)时跳转 |
BLE label | Z == 1 或 N ≠ V | 小于等于(Rn ≤ Rm,有符号)时跳转 |
BHI label | C == 1 且 Z == 0 | 大于(Rn > Rm,无符号)时跳转 |
BHS label | C == 1 | 大于等于(Rn ≥ Rm,无符号)时跳转 |
BLO label | C == 0 | 小于(Rn < Rm,无符号)时跳转 |
BLS label | C == 0 或 Z == 1 | 小于等于(Rn ≤ Rm,无符号)时跳转 |
2. ldr指令
格式: ldr pc,= 标签名
功能: 将PC指针指闻标签表示的地址

练习

答案

六、内存访问指令
1. 单内存访问指令
LDR 将内存中的值加载到寄存器(读内存)
STR 将寄存器的内容写入内存(写内存)
寄存器间接寻址:寄存器的值是一个地址
LDR ro,[r1 ] //r0 = *r1
STR ro,[ r1 ] //*r1 = ro
基址变址寻址:将基地址寄存器加上指令中给出的偏移量,得到数据存放的地址
- A. 前索引
STR r0,[r1,#4] //*(r1 + 4)= r0
LDR r0,[r1,#4] //r0 =*(r1+ 4)
- B. 后索引
STR r0,[r1],#4 //*r1=r0 &&r1=r1 + 4
LDR r0,[r1],#4 //r0=*r1 &&r1=r1 + 4
- C. 自动索引
STR r0,[r1,#4]! //*(r1+4)=r0&&r1=r1+4
LDR r0,[r1,#4]! //r0=*(r1+4)&&r1 =r1+4
示范:



练习
将1-10数据存放在基地址为0x4000,0000,将0x4000,0000起始地址的值拷贝到0x4000,0100
答案

将0x1234写到0x4000,0000,将0xabcd写到0x4000,0004,然后从这两个地址读取数据做案加,最终结果存放在r0
答案2

2. 多内存访问指令
LDM 将一块内存的数据,加载到多个寄存器中
STM 将多个寄存器的值,存储到一块内存
格式:
LDM{条件}{s}<MODE>基址寄存器{!},{Reglist}^
STM{条件}{s}<MODE>基址寄存器{!},{Reglist}^
| mode | 说明 |
|---|---|
| IA | 后增加地址 |
| IB | 先增加地址 |
| DA | 后减少地址 |
| DB | 先减少地址 |
基址寄存器
用于放内存的起始地址
!
最后更新基址寄存器的值
Reglist
- 多个寄存器,从小到大,中间用
,隔开,如{r0,r2,r3}或{r0-r7,r10} - 寄存器号大的对应内存的高地址,寄存器号小的对应内存的低地址
^
- 它存在,如果
Reglist没有pc的时候,这个时候操作的寄存器是用户模式下的寄存器 - 在
LDM指令中,有PC的时候,在数据传送的时候,会将SPSR的值拷贝到CPSR,用于异常的返回
流程图:


示例

3. 栈操作指令
A. 进栈
stmfd sp!,{寄存器列表}
B. 出栈
Idmfd sp!,{寄存器列表}
注意
在对栈操作之前,必须先设置sp的值,进栈和出栈的方式一样,ATPCS标准规定满减栈
流程图:

堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈
堆栈指针指向下一个待压入数据的空位置,称为空堆栈

示例

七、CPSR/SPSR操作指令
A. 读操作
MRS Rn,CPSR/SPSR
将状态寄存器的值,读到通用寄存器中
B. 写操作
MSR CPSR/SPSR,Rn
将通用寄存器的值,写到状态寄存器
练习
A.写一段代码,将CPSR的第I(7)位清0,其他位不变(使能IRQ异常)
B.写一段代码,将CPSR的第I(7)位置1,其他位不变(禁用IRQ异常)
答案

八、ARM指令流水线分析及伪指令
在ARM核中,为增加处理器指令流的速度,ARM7系列使用3级流水线。允许多个操作同时处理,而非顺序执行。不同的ARM核,流水线的级数是不一样的,ARM核版本越高,流水线级数越多。对于软件工程师编程而言,统一按照三级流水线来分析就可以了。
PC指向正被取指的指令,而非正在执行的指令

1. 最佳流水线

该例中用5个时钟周期执行了5条指令,所有的操作都在寄存器中(单周期执行)
指令周期数(CPI)=1
2. 内存访问指令流水线

该例中,用6周期执行了4条指令,指令周期数(CPI)=1.5
3. 分支流水线

4. ARM伪指令、汇编与C混合编程、Volatile关键字
伪指令定义:
为了方便程序员使用,编译器设计的指令,这个指令ARM核无法直接识别,需要编译器对他翻译成ARM核所能识别的指令。
(1)LDR R0,=0x12345678分析
再次强调:PC指向正被取指的指令,而非正在执行的指令
如何看内存中的12345678
正在读取的LDR内存是0x0008 加上 PC所在的地址(因为LDR正在执行 所以pc等于0x0000000C预取的值)
也就是0x0008加上pc的值0x0000000C等于0x00000014

总结
编译器在编译的时候,将Idr r0,=0x12345678翻译成了ldr r0,[pc,#0x0008]这一条读内存的指令。根据PC的值加上偏移量算出0x12345678这个数据在内存的地址,然后使用Idr指令读取这个地址的数据。
(2)LDR R0,=Label 分析
1) 链接地址指定为0x0情况分析
0x00000018等于0x000C加上pc的值0x000C
注意 0x00000018的值是14 这是个值 是编译器算出来的一个值


2) 链接地址指定为0x2000情况分析
修改链接地址

再运行
label的地址也就是0x000c+pc的值0x0000200c=0x00002018

3) 总结
LDR r0,=Label指令表示将Label的值写入r0,Label的值由指定的代码段运行地址(-Ttext=地址值)来决定。
编译器做法:
- 首先根据指定的代码段开始的地址,算出Label标签对应的地址值
- 然后将这个表示的地址值存放在一个位置
- 生成内存访问指令,根据pc +固定偏移量,找到标签对应值存放的位置
注意
当代码编译结束的时候,标签表示的地址值(根据指定的代码段地址)已经编译死存放在程序文件中了。
(3)LDR R0,Label
LDR R0,Label 表示读取Label表示的地址对应数据
不带=的时候 存的是标签里的内容

(4)ADR R0,Label分析
动态方式 根据pc的值+0x00000008
之前是静态的 在编译完的时候 label就已经确定值是什么了
这个是动态
举个例子:如果是用
LDR我把这个代码放到A内存和B内存运行
这两块内存的值是一模一样的 因为在编译完的时候 label就已经确定值是什么了
如果是ADRA内存的0x0008 和B内存的0x0008 是不一样的
有点难理解

ADR R0,Label指令表示根据当前的PC的值 +/-偏移量,动态获取当前Label所表示的内存地址
(5)如何判别代码在实际内存中运行的地址?
ADR r0,_start可以知道,因为他是根据pc的值,动态获取
LDR r0,=_start无法知道,这条指令不论在哪里运行,r0的值都是固定(取决于指定的链接地址)
相关文章:
【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令
文章目录 指令格式(重点)1. 立即数2. 寄存器位移 一、数据传送指令1. MOV指令2. MVN指令3. LDR指令 二、数据计算指令1. ADD指令1. SUB指令1. MUL指令 三、位运算指令1. AND指令2. ORR指令3. EOR指令4. BIC指令 四、比较指令五、跳转指令1. B/BL指令2. l…...
项目集成Nacos
文章目录 1.环境搭建1.创建模块 sunrays-common-cloud-nacos-starter2.目录结构3.pom.xml4.自动配置1.NacosAutoConfiguration.java2.spring.factories 5.引入cloud模块通用依赖 2.测试1.创建模块 sunrays-common-cloud-nacos-starter-demo2.目录结构3.pom.xml4.application.ym…...
QT交叉编译环境搭建(Cmake和qmake)
介绍一共有两种方法(基于qmake和cmake): 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别:CMake 和 qmake 都是自动化构建工具,用于简化构建过程,管理编译设置&…...
【某大厂一面】数组和链表区别
在 Java 中,数组(Array)和链表(LinkedList)是两种常见的数据结构,它们在存储和操作方式上有显著的区别。了解它们的差异有助于选择适合特定应用场景的结构。下面是数组和链表之间的详细比较。 1. 存储结构…...
基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结
title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付(CI/CD)流程里,及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...
一文大白话讲清楚webpack进阶——5——dev-server原理及其作用
文章目录 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用1. webpack的作用2. dev-server的作用3. dev-server的原理3.1 啥是webpack-dev-middleware3.2 HMR 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用 1. webpack的作用 webpack的作用我们之…...
[cg] 使用snapgragon 对UE5.3抓帧
最近想要抓opengl 的api,renderdoc在起应用时会闪退(具体原因还不知道),试了下snapgraon, 还是可以的 官网需要注册登录后下载,官网路径:Developer | Qualcomm 为了方便贴上已经下载好的exe安装包&#x…...
Java学习教程,从入门到精通,JDBC插入记录语法及案例(104)
JDBC插入记录语法及案例 一、JDBC插入记录语法 在JDBC中,插入记录主要通过执行SQL的INSERT语句来实现。其基本语法如下: INSERT INTO 表名 (列1, 列2, ..., 列n) VALUES (值1, 值2, ..., 值n);表名:需要插入记录的表的名称。列1, 列2, …,…...
物业巡更系统在现代社区管理中的优势与应用探讨
内容概要 在现代社区管理中,物业巡更系统正逐渐成为一种不可或缺的工具。结合先进的智能技术,这些系统能够有效地提升社区管理的各个方面,尤其是在巡检效率和信息透明度方面。通过实时记录巡检数据,物业管理人员能够确保工作人员…...
速通Docker === Docker Compose
目录 Docker Compose 简介 Docker Compose 常用命令 使用 Docker Compose 启动 WordPress 普通启动方式(使用 Docker 命令) 使用 Docker Compose 启动 Docker Compose 的特性 Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Dock…...
数据流中的第 K 大元素(703)
703. 数据流中的第 K 大元素 - 力扣(LeetCode) 解答: class KthLargest { public: //使用nums作为_q的底层存储,节省内存 KthLargest(int k, vector<int>& nums) : _k(k),…...
面试被问的一些问题汇总(持续更新)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
Spring MVC 综合案例
目录 一. 加法计算器 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 3. 服务器端代码 4. 运行测试 二. 用户登录 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 (1) 登录界面接口 (2) 首页接口 3. 服务器端代码 4. 运行测试 三. 留言板 1. 准备…...
数据分析系列--③RapidMiner算子说明及数据预处理
一、算子说明 1 新建过程 2 算子状态灯 状态灯说明: (1)状态指示灯: 红色:指示灯说明有参数未被设置或输入端口未被连接等问题; 黄色:指示灯说明还未执行算子,不管配置是否基本齐全; 绿色:指示灯说明一切正常,已成功执行算子。 (2)三角…...
NLP自然语言处理通识
目录 ELMO 一、ELMo的核心设计理念 1. 静态词向量的局限性 2. 动态上下文嵌入的核心思想 3. 层次化特征提取 1. 双向语言模型(BiLM) 2. 多层LSTM的层次化表示 三、ELMo的运行过程 1. 预训练阶段 2. 下游任务微调 四、ELMo的突破与局限性 1. 技术突破 2. …...
Time Constant | RC 和 RL 电路中的时间常数
注:本文为 “Time Constant” 相关文章合辑。 机翻,未校。 How To Find The Time Constant in RC and RL Circuits June 8, 2024 💡 Key learnings: 关键学习点: Time Constant Definition: The time constant (τ) is define…...
无心剑七绝《除夕快乐》
七绝除夕快乐 除旧迎新瑞气扬 夕阳烂漫映红妆 快言美酒佳肴味 乐享天伦福满堂 2025年1月28日 平水韵七阳平韵 无心剑这首七绝以“除夕快乐”为题,巧妙地运用了藏头手法,将“除夕快乐”四字分别嵌入诗的每一句首字,构思精巧,富有新…...
Object类(3)
大家好,今天继续给大家介绍一下object类中的方法,那么话不多说,来看。 hashcode()这个方法,帮我们算了一个具体的对象位置,这里面涉及到数据结构,简单认为它是个内存地址,然后调用Integer.toHexString ()将这个地址以16进制输出。 该方法是一…...
Vue.js组件开发-实现下载动态进度条
在Vue.js中,可以通过创建一个自定义组件来实现下载动态进度条。这个组件可以接收下载的进度作为prop,并根据这个进度动态地更新进度条。 首先 需要创建一个Vue组件,比如DownloadProgressBar.vue: <template><div clas…...
GPU上没程序在跑但是显存被占用
原因:存在僵尸线程,运行完但是没有释放内存 查看僵尸线程 fuser -v /dev/nvidia*关闭僵尸线程 pkill -9 -u 用户名 程序名 举例:pkill -9 -u grs python参考:https://blog.csdn.net/qq_40206371/article/details/143798866...
2007-2020年各省国内专利申请授权量数据
2007-2020年各省国内专利申请授权量数据 1、时间:2007-2020年 2、来源:国家统计局、统计年鉴 3、指标:行政区划代码、地区名称、年份、国内专利申请授权量(项) 4、范围:31省 5、指标解释:专利是专利权的简称&…...
常见端口的攻击思路
端口号端口说明攻击方向21/22/69FTP/TFTP文件传输协议匿名上传/下载、嗅探、爆破2049NFS服务配置不当139Sanba服务爆破、远程代码执行389Ldap目录访问协议注入、匿名访问、弱口令22SSH远程连接爆破、SSH映射隧道搭建、文件传输23Telnet远程连接爆破、嗅探、弱口令3389RDP远程桌…...
python:洛伦兹变换
洛伦兹变换(Lorentz transformations)是相对论中的一个重要概念,特别是在讨论时空的变换时非常重要。在四维时空的背景下,洛伦兹变换描述了在不同惯性参考系之间如何变换时间和空间坐标。在狭义相对论中,洛伦兹变换通常…...
电路研究9.2.3——合宙Air780EP中FTP——FTPGET 命令使用方法研究
怎么说呢,之前也是看的,但是也很迷茫,感觉上虽然是对的,但是无法联系到应用里面,今天研究一下FTP 命令使用方法吧。 15.29 使用方法举例 这里发现下面那些看的不懂呢,于是就返回FTP的应用了。 9.5.4 FTP 应…...
HTML 标题
HTML 标题 引言 HTML(超文本标记语言)是构建网页的基础,而标题则是网页中不可或缺的元素。标题不仅能够帮助用户快速了解网页内容,还能够对搜索引擎优化(SEO)产生重要影响。本文将详细介绍HTML标题的用法…...
npm cnpm pnpm npx yarn的区别
npm、cnpm、pnpm、npx、yarn 这几个工具都与 Node.js 项目的包管理和命令执行相关,它们的区别具体如下: 本质与功能定位 npm:是 Node.js 官方的包管理工具,提供了安装、卸载、更新、发布等全方位的包管理功能,还能通…...
redis缓存和springboot缓存包冲突怎么办
如果Redis缓存与Spring Boot缓存包发生冲突,可以采取以下几种解决方案: 排除Spring Boot缓存包:在pom.xml文件中排除Spring Boot的缓存依赖,以避免与Redis缓存冲突。例如: <dependency><groupId>org.spr…...
ANSYS学习笔记(十)网格质量的诊断和提高
网格质量的好坏不能单纯只看meshing给出的网格质量结果,要根据实际的计算物理场景来判断,需要求解的地方物理量大梯度的位置网格越密越好。 网格质量:在有限网格数量限制下,离散误差小的网格是好网格,是高质量网格。网…...
ChatGPT 搜索测试整合记忆功能
据 TestingCatalog 报道,OpenAI 正在测试 ChatGPT 搜索的整合记忆功能,被命名为 “Memory in search”2。以下是关于该功能的具体情况123: 功能特点 个性化搜索:启用该功能后,ChatGPT 能利用存储的记忆数据࿰…...
在Ubuntu上使用Apache+MariaDB安装部署Nextcloud并修改默认存储路径
一、前言 Nextcloud 是一款开源的私有云存储解决方案,允许用户轻松搭建自己的云服务。它不仅支持文件存储和共享,还提供了日历、联系人、任务管理、笔记等丰富的功能。本文将详细介绍如何在 Ubuntu 22.04 LTS 上使用 Apache 和 MariaDB 安装部署 Nextcl…...
