ARMday03(寄存器读写、栈、程序状态寄存器、软中断和异常、混合编程)
单寄存器内存读写指令
将一个寄存器中的数值写入到内存,或者从内存中读取数据放在某一个指定寄存器中
指令码和功能
1.向内存中写:
str{条件码} 目标寄存器,[目标地址]:将目标寄存器的4字节数值写入到目标地址为首地址的空间中
strh{条件码} 目标寄存器,[目标地址]:将目标寄存器的2字节数值写入到目标地址为首地址的空间中
strb{条件码} 目标寄存器,[目标地址]:将目标寄存器的1字节数值写入到目标地址为首地址的空间中
2.从内存中读:
ldr{条件码} 目标寄存器,[目标地址]:从目标地址为首地址的空间中读取4字节数据存放在目标寄存器中
ldrh{条件码} 目标寄存器 ,[目标地址]:从目标地址为首地址的空间中读取2字节数据存放在目标寄存器中
ldrb{条件码} 目标寄存器 ,[目标地址]:从目标地址为首地址的空间中读取1字节数据存放在目标寄存器中
单寄存器内存索引方式
前索引方式
str{条件码} 目标寄存器,[目标地址,#立即数] //将目标寄存器的数据保存在目标地址+8为起始地址的内存中
ldr{条件码} 目标寄存器,[目标地址,#立即数] //从目标地址+8为起始地址的内存中读取数据保存在目标寄存器
后索引方式
str{条件码} 目标寄存器,[目标地址],#立即数 //将目标寄存器的数据保存在目标地址为起始地址的内存中,接着目标地址自加立即数大小
ldr{条件码} 目标寄存器,[目标地址],#立即数 //从目标地址为起始地址的内存中读取数据保存在目标寄存器,接着目标地址自加立即数大小
自动索引方式
str{条件码} 目标寄存器,[目标地址,#立即数]! //将目标寄存器的数据保存在目标地址+立即数为起始地址的内存中,接着目标地址自加立即数大小
ldr{条件码} 目标寄存器,[目标地址,#立即数]! //从目标地址+立即数大小为起始地址的内存中读取数据保存在目标寄存器,接着目标地址自加立即数大小
批量寄存器的内存读写方式
指令码以及格式
向内存写: stm 目标地址,{目标寄存器列表} 将列表中各个寄存器的数值保存在目标地址对应的地址空间中
从内存中读取 ldm 目标地址,{目标寄存器列表} 从目标地址对应的地址空间中拿数据保存到寄存器列表中各个寄存器中
注意:
1.寄存器列表中每一个寄存器之间用','分隔,如果寄存器列表中寄存器的编号连续,那么可以用-表示一定范围内的 寄存器,比如 {r1-r5}
2.无论寄存器列表中的寄存器表现形式如何,在存取数据时始终是小编号寄存器对应低地址
批量寄存器的地址增长方式
内存读写命令后加ia后缀
先向r0数值为起始地址的内存空间中保存一个数据,然后r0数值往高地址方向增长
内存读写命令后加ib后缀
先r0数值往高地址方向增长,然后向r0数值为起始地址的内存空间中保存一个数据
内存读写命令后加da后缀
先向r0数值为起始地址的内存空间中保存一个数据,然后r0数值往低地址方向增长
内存读写命令后加db后缀
先r0数值往低地址方向增长,然后向r0数值为起始地址的内存空间中保存一个数据
栈内存的读写
栈指针寄存器:SP/R13 保存栈顶的地址
栈:本质上就是一段内存。在内存中选取一段内存作为栈内存,可以用于保存临时数据。
栈的类型
增栈:每次压栈结束,SP保存的栈顶地址往高地址方向增栈
减栈:每次压栈结束,SP保存的栈顶地址往低地址方向增栈
空栈:压栈结束后,SP保存的栈顶空间中没有有效数据
满栈:压栈结束后,SP保存的栈顶空间中有有效数据
空增栈(EA)/空减栈(ED)/满增栈(FA)/满减栈(FD)
当前ARM处理器使用的是哪种栈?满减栈

满减栈压栈出栈操作
1.
push {寄存器列表}@压栈
pop {寄存器列表}@出栈
2.
stmdb sp!,{r1-r5}@压栈
ldmia sp!,{r6-r10}@出栈
3.
stmfd sp!,{r1-r5}@压栈
ldmfd sp!,{r6-r10}@出栈
叶子函数
当我们在主函数中调用一个函数,被调用的这个函数中没有别的函数调用,那么 这个函数就叫做叶子函数。栈的应用------保护现场
.text
.global _start _start:
@初始化栈ldr SP,=0X40000020b main
main:mov r1,#3mov r2,#4bl fun1add r3,r1,r2b main
fun1:
@压栈保护现场stmfd sp!,{r1,r2}mov r1,#7mov r2,#9sub r4,r2,r1@出栈恢复现场ldmfd sp!,{r1,r2}mov pc,lr @程序返回.end
非叶子函数
当我们在主函数中调用一个函数,被调用的这个函数中存在别的函数调用,那么 这个函数就叫做非叶子函数
.text
.global _start _start:
@初始化栈ldr SP,=0X40000020b main
main:mov r1,#3mov r2,#4bl fun1add r3,r1,r2b main
fun1:
@压栈保护现场stmfd sp!,{r1,r2,lr}mov r1,#7mov r2,#9bl fun2sub r4,r2,r1@出栈恢复现场ldmfd sp!,{r1,r2,lr}mov pc,lr @程序返回
fun2:stmfd sp!,{r1,r2}mov r1,#4mov r2,#8mul r4,r2,r1@出栈恢复现场ldmfd sp!,{r1,r2}mov pc,lr @程序返回.end
程序状态寄存器传输指令
指令的作用实现CPSR寄存器数值的读取以及数值的修改
指令码以及格式
格式:
注意:这两条指令只能对特殊功能寄存器进行操作(CPSR),不能对普通寄存器进行操作
msr CPSR,第一操作数 将第一操作数的数值写入到CPSR寄存器中
mrs 目标寄存器,CPSR 读取CPSR数值保存到目标寄存器中
软中断指令
软中断是从软件层次上模拟的硬件中断,原理和硬件中断一样。软中断触发之后CPU进行异常模式的切换(SVC),紧接着执行软中断对应的异常处理程序。
软中断指令码以及使用
swi 中断号
注意:中断号是一个由24位二进制数组成的一个整数,用于区分不同的中断
异常处理过程分析
异常模式和异常源的对应关系
5种异常模式对应7种异常源

异常的处理过程分析(面试重点)
***********异常的处理过程********
当一个异常源产生之后CPU会进行一些工作用于程序的跳转以及异常模式的切换,这个过程分为四大步三小步
1.保存发生异常之前的CPSR的值到对应异常模式下的SPSR寄存器中
2.修改CPSR的数值
2.1 根据实际情况设置FIQ和IRQ中断禁止 CPSR[7:6]
2.2 修改处理器工作状态为ARM状态 CPSR[5]
2.3 修改处理器的工作模式为对应的异常模式 CPSR[4:0]
3.保存主程序的返回地址到对应模式下的LR寄存器中
4.修改PC的值到对应异常模式下的异常向量表中
*********处理完异常之后现场的恢复过程*********
1.恢复CPSR寄存器的值为未发生异常之前的状态
2.修改PC的值为未发生异常之前的下一条指令地址 PC=LR
异常向量表
1.异常向量表是内存空间中的一段内存。这段内存占据了32字节。这个内存被平分为8等份,一份是4字节。每一份内存对应一种异常源,有一份保留,在异常向量表内存里存放的是当前异常源对应的异常处理程序的跳转指令。当发生异常之后,CPU会修改PC的值为对应异常源在异常向量中的位置,执行这个位置中的跳转指令,去处理异常处理程序。
2.每一种异常源在异常向量表中的位置是固定,不能随便修改
3.只要设置了异常向量表的基地址,就可以根据不同异常在一场向量表中的位置找到对应异常的跳转指令

混合编程
混合编程的意义
所谓的混合编程就是c语言资源和汇编资源的相互调用
- 一般工程会有汇编启动程序,启动程序完成堆栈的相关初始化,完毕之后才跳转到c语言的main函数
- c语言中几乎不可以直接操作寄存器,但是有些特定场景下需要c中操作寄存器,这时候就需要c语言中嵌套汇编的语法
汇编调用C语言的函数
*****汇编文件**********
.text
.global _start _start: @ 1. 初始化栈指针,C代码运行必须有栈ldr sp, =0x40000820@ 2. 汇编调用c函数 @ 2.1 给C的函数传递实参值mov r0, #3 @ a = 3mov r1, #4 @ b = 4mov r2, #5 @ c = 5mov r3, #6 @ d = 6@ 2.2 汇编调用c的函数bl add_func@ 2.3 函数的返回通过r0返回,查看r0寄存器中的值loop: b loop .end**********c文件********************
// c代码的函数是一个全局的函数
int add_func(int a, int b, int c, int d)
{return (a+b+c+d);
}
c语言调用汇编标签
********起始汇编文件**********
.text
.globl _start _start: @ 1. 初始化栈指针,C代码运行必须有栈ldr sp, =0x40000820@ 2. 汇编调用c,跳转到main函数b main
.end********c文件************
// 使用extern对函数进行声明
extern int add_func(int a, int b, int c, int d);int sum = 0;
int main()
{// 在c代码中调用汇编代码sum = add_func(1,2,3,4);while(1);return 0;
}********汇编文件**********
.text
.global add_func @ 将add_func函数声明为全局add_func:add r0, r0, r1add r0, r0, r2add r0, r0, r3mov pc, lr
.end
c语言内联汇编
在某一些特定的场景下需要在c语言中直接使用汇编的语法,此时需要内联汇编。内联汇编的实现需要通过asm关键字进行修饰
asm volatile("汇编指令模板\n\t" //"\n\t"表示一条指令的结束.....:输出列表 //指令结果的输出值:输入列表 //指令的数据输入:破坏列表 //破坏列表指定我们当前可用的寄存器
);
相关文章:
ARMday03(寄存器读写、栈、程序状态寄存器、软中断和异常、混合编程)
单寄存器内存读写指令 将一个寄存器中的数值写入到内存,或者从内存中读取数据放在某一个指定寄存器中 指令码和功能 1.向内存中写: str{条件码} 目标寄存器,[目标地址]:将目标寄存器的4字节数值写入到目标地址为首地址的空间中 strh{条件码…...
Excel中功能区的存放位置很灵活,可以根据需要隐藏或显示
在这个简短的教程中,你将找到5种快速简单的方法来恢复Excel功能区,以防丢失,并学习如何隐藏功能区,为工作表腾出更多空间。 功能区是Excel中所有操作的中心点,也是大多数可用功能和命令所在的区域。你觉得功能区占用了你太多的屏幕空间吗?没问题,只需单击鼠标,它就被隐…...
HelloGitHub 社区动态,开启新的篇章!
今天这篇文章是 HelloGitHub 社区动态的第一篇文章,所以我想多说两句,聊聊为啥开启这个系列。 我是 2016 年创建的 HelloGitHub,它从最初的一份分享开源项目的月刊,现如今已经成长为 7w Star 的开源项目、1w 用户的开源社区、全网…...
【学术综述】-如何写出一篇好综述-写好综述要注意的问题
文章目录 1.前置1.1 SSD 的结构1.2 FTL的架构和作用 2 动机-why?3 做了什么【做了哪些方面的survey】?4 背景知识【上下文】5 研究的问题6 每个问题对应的解决方案 从昨天晚上【2023.11.09 22:00】到今天22:29的,花了一天的时间在读这篇surve…...
ClickHouse介绍和使用
ClickHouse介绍和使用 1. 简介2. ClickHouse特点3. 数据类型3.1. 整型3.2. 浮点型3.3. Decimal型3.4. 布尔型3.5. 字符串3.6. 枚举类型3.7. 时间类型 4. 表引擎4.1. TinyLog4.2. Memory4.3. MergeTree4.3.1. partition by分区(可选)4.3.2. primary key 主…...
数码管动态扫描
/*----------------------------------------------- 内容:数码管使用动态扫描显示,所以可以同时看到数码管同时显示数字或者字符。 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不…...
Webpack 中 loader 的作用是什么?常用 loader 有哪些?
说说webpack中常见的Loader?解决了什么问题?- 题目详情 - 前端面试题宝典 1、loader 是什么 loader是 webpack 最重要的部分之一。 通过使用不同的 loader,我们能够调用外部的脚本或者工具,实现对不同格式文件的处理。 loader…...
c#,字段和属性的区别
c#,string test和string test{ges;set;}有什么区别 在C#中,string test和string test { get; set; }表达了两种不同的成员声明,它们在类中的作用和访问方式是不同的。 string test: 这是一个字段(field)声明。它声明了一个类型…...
ideal一键部署SpringBoot项目jar包到服务器
一 简介 我们在开发环境部署项目一般通过ideal将项目打包成jar包,然后连接linux服务器,将jar手动上传到服务中,重启服务。 概括的说流程是这样的: 本地打包->上传到服务器->kill掉以前的服务->重新启动jar包服务 每次总是循环这一…...
宝塔部署QQ机器人,提示OpenSSL 1.0.2k-fips 26 Jan 2017
1、报错预览 Traceback (most recent call last):File "/www/wwwroot/python/bot-one/main.py", line 5, in <module>import requestsFile "/www/wwwroot/python/bot-one/343ae0eb0d491a10a1a00c0621b03ed0_venv/lib/python3.9/site-packages/requests/_…...
K8S篇之简述K8S底层原理
k8s底层原理 Kubernetes(简称k8s)是一个开源的容器编排平台,它可以自动化地部署、扩展和管理容器化应用程序。 Kubernetes 底层原理是其能够实现这些功能的关键。 1 节点和控制平面 Kubernetes 由两个主要组件组成:节点Node和控…...
打开ps提示,计算机中丢失d3dcompiler_47.dll怎么解决?
“d3dcompiler_47.dll丢失5个解决办法”。相信很多同事在工作或者娱乐的过程中,都遇到过这个错误提示。那么,究竟什么是d3dcompiler_47.dll文件?为什么会丢失呢?又该如何解决这个问题呢?接下来,我将为大家详…...
torch.mm
torch.mm(input, mat2, *, outNone) → Tensor执行矩阵input和mat2的矩阵乘法运算。 如果input是(nm)张量,mat2是(mp)张量,out将是(n x p)张量。 input(张量࿰…...
github遇到想要强制拉取远程仓库内容
进行项目的时候,遇到了我的远程仓库 Sync fork 更新以后,这时候我的本地就和远程不同步,如果使用 git pull 的时候,如果出现 conficts 过多的情况怎么办,如果我们想要直接把远程仓库拉下来应该怎么办? git…...
django+drf+vue 简单系统搭建 (2) - drf 应用
按照本系统设置目的,是为了建立一些工具用来处理简单的文件。 1. 准备djangorestframework 关于drf的说明请参见:Django REST Framework教程 | 大江狗的博客 本系列直接使用drf的序列化等其他功能。 安装 conda install djangorestframework conda i…...
【FastCAE源码阅读7】视图方向切换按钮实现原理
在FastCAE工具栏上有视图切换按钮,如下图所示: 本文介绍如何实现。 FastCAE集成了Python解析器,当单击按钮时,中间用Python执行的,最后调用MainWindow.dll库接口实现的。 具体的Python代码在Python模块的py文件夹下的…...
小程序如何设置自取模式下的服务方式
设置自取模式下的服务方式是非常重要的,尤其是对于到店自取和到店堂食这两种不同的服务模式。下面我们就来介绍一下如何在小程序中设置这两种服务方式。 在小程序管理员后台->配送设置处,在服务方式处,设置自取情况下的服务方式。默认是&…...
使用数据分析,识别设备异常
设备健康监测系统在工业领域中扮演着至关重要的角色,它能够帮助企业及时发现设备异常,预防故障,提高设备使用寿命和生产效率。而异常诊断技术则是设备健康监测系统中的核心部分,能够实现对设备异常情况的准确判断。根据设备状态数…...
redis数据倾斜如何解决
Redis数据倾斜主要是由于数据访问热点导致的,通常在执行事务操作或范围查询时发生。这会导致大量数据集中在某个实例上,使得集群负载不均衡。以下是一些解决Redis数据倾斜的方法: 避免在同一个键值对上保存过多的数据。可以将大的键值对拆分…...
ATFX汇市:美联储鲍威尔再发鹰派言论,美元指数逼近106关口
ATFX汇市:11月10日,美联储主席鲍威尔在IMF举办的专家小组会议上讲话称:“如果进一步收紧货币政策变得合适,美联储‘将毫不犹豫地’这样做。”他还提到,对目前通胀进展感到满意,但“还有很长的路要走”。鲍威…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
