Linux 学习记录53(ARM篇)

Linux 学习记录53(ARM篇)

在这里插入图片描述

本文目录

  • Linux 学习记录53(ARM篇)
  • 一、内存读写指令
    • 1. 在C语言中读取内存
    • 2. 指令码及功能
    • 3. 格式
    • 4. 使用示例
    • 5. 寻址方式
      • (1. 前索引方式
      • (2. 后索引方式
      • (3. 自动索引
    • 6.批量寄存器操作指令
      • (1. 操作码
      • (2. 格式
      • (3. 使用示例
      • (4. 地址增长方式
        • >1 ia后缀
        • >2 ib后缀
        • >3 da后缀
        • >4 db后缀
  • 二、栈内存的读写
    • 1. 概述
    • 2. 栈的类型
    • 3. 满减栈的压栈和出栈实现
    • 4. 叶子函数和非叶子函数
  • 三、状态寄存器CPSR读写指令
    • 1. 指令码及格式
    • 2. 使用示例
    • 3. 注意事项
  • 四、软中断指令
    • 1. 概念
    • 2. 指令码和格式
    • 3. ARM异常处理过程分析
      • (1. ARM异常源以及异常模式
      • (2. 异常的处理过程分析
      • (3. 异常向量表
      • (4. swi异常处理代码

一、内存读写指令

在下图界面中可以搜索指定的内存地址
在这里插入图片描述

1. 在C语言中读取内存

例如已知可以访问的地址为:0x12345678(unsigned int*)0x12345678//将其强制转换为unsigned int类型的地址
*((unsigned int*)0x12345678)//获取0x12345678地址下的数据

2. 指令码及功能

写内存:
1. str:向指定内存中写入一个字的数据
2. strh:向内存中写入半个字的数据
3. strb:向内存中写入一个字节的数据
读内存:
4. ldr:从内存中读取一个字的数据
5. ldrh:从内存中读取半个字的数据
6. ldrb:从内存中读取一个字节的数据

3. 格式

指令码{条件码} 目标寄存器 [目标地址]
例如:
str r1,r0]  将目标寄存器的数值写入到目标地址对应的内存中
ldr r1,[r0]  在目标地址中读取一个字的数据到

4. 使用示例

.text   
.global _start   
_start:mov r0,#0x40000000mov r1,#0xffffffffstr r1,[r0] @将r1中的数据写一个字到0x40000000内存中
stop:b stop  
.end    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 寻址方式

(1. 前索引方式

.text   
.global _start   
_start:mov r0,#0x40000000mov r1,#0xffffffff@前索引方式str r1,[r0,#8] @将r1中的数据写一个字到0x40000000+8的内存中ldr r2,[r0,#8] @读取r0+8对应的地址内存中的一个字的数据到r2中
stop:b stop  
.end  

在这里插入图片描述
在这里插入图片描述

(2. 后索引方式

.text   
.global _start   
_start:mov r0,#0x40000000mov r1,#0xffffffff@后索引方式 完成一次存储后r0寄存器会自动偏移8str r1,[r0],#8 @将r1中的数据写一个字到0x40000000的内存中
stop:b stop  
.end  

在这里插入图片描述

在这里插入图片描述

(3. 自动索引

结合了前两者的索引方式

.text   
.global _start   
_start:mov r0,#0x40000000mov r1,#0xffffffff@自动索引方式 完成一次存储后r0寄存器会自动偏移8str r1,[r0,#8]! 	@将r1中的数据写一个字到0x40000000+8的内存中
stop:b stop  
.end  

在这里插入图片描述

在这里插入图片描述

6.批量寄存器操作指令

(1. 操作码

1. stm 写
2. ldm 读

(2. 格式

stm rm,{寄存器列表}:将寄存器列表中每一个寄存器的数值存放到以rm数值为起始地址的内存中
ldm rm,{寄存器列表}:从rm数值为起始地址的内存中 读取指定数量的数据到寄存器列表中每一个寄存器内解释:1.rm:存放操作的内存首地址的寄存器2.关于寄存器列表中的寄存器的表达方式:如果寄存器列表中寄存器编号连续,可以用-表示范围  {r7-r11}如果寄存器列表中寄存器的编号不连续,可以用','分隔 {r7,r8,r9,r10,r11}3.无论寄存器列表中的寄存器顺序是什么样的,在操作内存时始终是低地址对应小编号寄存器ex:ldm r6,{r11,r10,r9,r7,r8}  虽然列表中寄存器顺序散乱,但是r7是对应最小的地址数值

(3. 使用示例

.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5mov r6,#0x40000000stm r6,{r1-r5} 	@将r1-r5寄存器的数据批量存放到内存中stm r6,{r1,r2,r3,r4,r5} 	@将r1-r5寄存器的数据批量存放到内存中ldm r6,{r7-r11} @将内存中的数据批量读取到r7-r1寄存器中stop:b stop  .end   

在这里插入图片描述
在这里插入图片描述

(4. 地址增长方式

>1 ia后缀

ia后缀:先往指定的寄存器数值为起始地址中存放数据,然后该寄存器数值自动偏移
例:stmia r6!,{r1-r5}

.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5mov r6,#0x40000000stmia r6!,{r1-r5}stop:b stop  .end  

在这里插入图片描述

>2 ib后缀

ib后缀:先让指定寄存器的数值增大,再存放数据

.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5mov r6,#0x40000000stmib r6!,{r1-r5}stop:b stop  .end  

在这里插入图片描述
在这里插入图片描述
可以看到是先偏移在存放数据

>3 da后缀

da后缀:先存放后再向小地址偏移

.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5ldr r6,=0x40000800stmda r6!,{r1-r5}stop:b stop  .end  

在这里插入图片描述
在这里插入图片描述

>4 db后缀

db后缀:先偏移后存放

.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5ldr r6,=0x40000800stmdb r6!,{r1-r5}stop:b stop  .end  

在这里插入图片描述
在这里插入图片描述
可以看到是先从0800偏移后再存放的数据

二、栈内存的读写

1. 概述

栈指针寄存器(R13 [SP]),sp始终保存栈顶元素的首地址
栈的本质就是一段内存空间,被分出来用于存放一些临时数据,我们可以用过对栈区内存读写来保护现场

2. 栈的类型

1. 增栈:基于栈指针寄存器完成压栈之后,栈指针的数组往地址大的方向增长
2. 减栈:基于栈指针寄存器完成压栈之后,栈指针的数组往地址小的方向增长
3. 空栈:压栈结束后,栈指针寄存器保存的地址内存中没有有效数据(先压栈再增长地址)
4. 满栈:压栈结束后,栈指针寄存器保存的地址内存中存放追后一次压栈的数据(先增长地址,再压栈)

栈的类型可以分为:空增(EA)、空减(ED)、满增(FA)、满减(FD)

ARM处理器默认采用满减栈实现压栈和出栈

3. 满减栈的压栈和出栈实现

.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5ldr sp,=0x40000800 	@初始化栈stmdb sp!,{r1-r5}	@压栈用dbldmia sp!,{r7-r11}	@出栈用iastop:b stop  .end  
======================================
采用满减栈特有后缀 "fd"
.text   
.global _start   
_start:mov r1,#1mov r2,#2mov r3,#3mov r4,#4mov r5,#5ldr sp,=0x40000800 	@初始化栈stmfd sp!,{r1-r5}	@压栈用dbldmfd sp!,{r7-r11}	@出栈用iastop:b stop  .end  

在这里插入图片描述
在这里插入图片描述

4. 叶子函数和非叶子函数

叶子函数:函数中没有再调用其他函数的函数称为叶子函数

在使用汇编指令跳转时,如果在非叶子函数再次发生跳转时就需要使用通过压栈的方式来对当前函数内现场进行保护,防止数据被覆盖后原有现场被破坏

.text   
.global _start   _start:@栈的初始化LDR SP,=0X40000800b main
main:mov r1,#1mov r2,#2bl fun1add r3,r1,r2b main
fun1:
@ 压栈 保护现场,非叶子函数内部调用其他函数,lr的数值也会被覆盖,所以需要将它压栈保护stmfd sp!,{r1,r2,lr}mov r1,#5mov r2,#2bl fun2sub r4,r1,r2@出栈恢复现场ldmfd sp!,{r1,r2,pc}fun2:@ 压栈 保护现场stmfd sp!,{r1,r2}mov r1,#6mov r2,#4mul r5,r1,r2@出栈恢复现场ldmfd sp!,{r1,r2}mov pc,lr  @函数返回stop:b stop   .end  

在这里插入图片描述

三、状态寄存器CPSR读写指令

1. 指令码及格式

读:
MRS Rd,CPSR:将CPSR寄存器的数值读取到目标寄存器中
写:
MSR cpsr,操作数:将操作数写道CPSR寄存器中

2. 使用示例

从复位模式切换到USER模式

.text   
.global _start   _start:mrs r0,cpsr	@读取CPSR寄存器bic r0,r0,#0x1F	@低5位清零orr r0,r0,#0x10	@给定数值msr cpsr,r0		@将修改后的值赋值stop:b stop   .end  

在这里插入图片描述

3. 注意事项

USER模式作为唯一的非特权模式,我们不能直接修改CPSR的值切换至其他特权模式,为例保护系统
想要从USER模式切换到其他模式,需要特定的异常出现,才能切换到对应的模式

四、软中断指令

1. 概念

从软件层次上模拟的一个中断,用于ARM从工作模式从USER模式切换到特权模式

2. 指令码和格式

swi 中断号
注意:
1. swi是软中断的指令码
2. 中断号是系统中的中断标识,是由24位数据组成的一个立即数

3. ARM异常处理过程分析

(1. ARM异常源以及异常模式

(5种异常模式对应7种异常源)

异常模式异常源解释
FIQ异常模式FIQ类型异常源引发程序进入FIQ模式的异常事件
IRQ异常模式IRQ类型异常源引发程序进入IRQ模式的异常事件
SVC异常模式复位信号按键复位/上电复位
SVC异常模式swi软中断指令swi 软中断号
undef异常模式未定义异常源译码器翻译指令时,无法编译成功,指令未定义
abort异常模式data abort取数据发生中断
abort异常模式prefetch abort取指令发生中断
五种异常工作模式,对应七种异常源
1. 当发生对应类型的异常源时
2. 则处理器会进入到异常的工作模式
3. 执行异常处理程序,完成某个特定的功能
4. 五种异常工作模式,对应七种异常源,异常源优先级
5. 复位的优先级最高

(2. 异常的处理过程分析

**********处理过程*********
保存现场:这个过程是由CPU自动完成(四大步三小步)
1.保存CPSR到SPSR_<MODE>寄存器中
2.修改CPSR寄存器:1>修改状态位(T位),切换到ARM状态2>根据需要禁止IRQ和FIQ中断位3>修改CPSR寄存器中的模式位,切换到对应的异常模式 M[4:0]
3.保存返回地址到LR_<MODE>
4.修改PC指针,指向对应的异常向量表**************恢复过程***********
1.恢复SPSR_<mode>寄存器中的值,到CPSR寄存器中
2.恢复LR_<mode>寄存器中的值,到PC寄存器中
1)保存现场是CPU自动完成的,当发生异常时,CPU自动完成保存现场过程
2)当修改PC指针,指向异常处理程序的入口时
3)由于异常处理程序的入口地址不固定
4)所以ARM公司设计引入异常向量表

(3. 异常向量表

1.异常向量表是代码段的一块空间,这块空间大小是32字节,被平均分成了8份,每份占用4个字节
2.异常向量表存放7种异常源对应的异常处理函数的跳转指令,有一份保留
3.7种异常源在异常向量表中的位置是固定的,不可以随意更改
4.只需要指定异常向量表的基地址,根据异常源在异常向量表中的偏移地址,就可以确定异常源在异常向量表中的位置
中断向量地址异常中断类型异常中断模式优先级(6最低)
0x0复位特权模式(SVC)1
0x4未定义的指令未定义指令中止模式(Undef)6
0x8软件中断(SWI)特权模式(SVC)6
0x0c指令预取中止中止模式5
0x10数据访问中止中止模式2
0x14保留未使用未使用
0x18外部中断请求(IRQ)外部中断(IRQ)模式4
0x1c快速中断请求(FIQ)快速(FIQ)中断模式3

(4. swi异常处理代码

.text   
.global _start   _start:@初始化异常向量表b main  @复位异常b .      @undef异常b do_swi  @软中断异常b .    @指令中止b .    @数据中止b .    @保留b .    @IRQ异常b .    @FIQ异常main:@初始化栈LDR SP,=0X40000800@切换到USER模式MSR CPSR,#0X10mov r1,#1mov r2,#2@触发软中断swi 1add r3,r1,r2b main
do_swi:
@压栈保护现场STMFD SP!,{R1,R2,LR}mov r1,#3mov r2,#5mul r4,r1,r2@恢复现场返回主程序执行LDMFD SP!,{R1,R2,PC}^   @^的作用是修改PC数值的同时将SPSR数值赋值给CPSR
stop:b stop   .end   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

========Java基础——小结1========

一、Java 两大版本 Java 主要分为两个版本: Java SE 和Java EE。 Java SE 全称Java Platform Standard Edition&#xff0c;是 Java 的标准版&#xff0c;主要用于桌面应用程序开发&#xff0c;它包含了 Java 语言基础、JDBC (Java 数据库连接)、I/O (输入/输出)、TCP/IP 网络…

股票基金入门知识

1.开盘价和收盘价如何产生 时间9:30-11:30 13:00-15:00 集合竞价时间段&#xff1a;9:15-9:25 以此产生开盘价 最后集中竞价时间段&#xff1a;深市14:57-15:00 &#xff0c;以此产生收盘价。 沪市则采用最后一分钟加权得出收盘价影响股价的因素 市场投资情绪&#xff0c;宏观…

Hadoop——DataGrip连接MySQL|Hive

1、下载 DataGrip下载&#xff1a;DataGrip: The Cross-Platform IDE for Databases & SQL by JetBrains 2、破解 破解链接&#xff1a;https://www.cnblogs.com/xiaohuhu/p/17218430.html 3、启动环境 启动Hadoop&#xff1a;到Hadoop的sbin目录下右键管理员身份运行…

【C++】list 模拟笔记

文章目录 list定义结点类&#xff08;list_node&#xff09;为什么封装迭代器为类 &#xff1f;库里面模板多参数的由来 &#xff1f;为什么普通迭代器不能隐式类型转换成const迭代器&#xff1f;迭代器位置指向及其返回值和整体代码 list list 和前面学习的 string 和 vector …

微信小程序使用ECharts的示例详解

目录 安装 ECharts 组件使用 ECharts 组件图表延迟加载 echarts-for-weixin 是 ECharts 官方维护的一个开源项目&#xff0c;提供了一个微信小程序组件&#xff08;Component&#xff09;&#xff0c;我们可以通过这个组件在微信小程序中使用 ECharts 绘制图表。 echarts-fo…

excel中单行换成多行

今天碰以下情况&#xff1a; 这在excel表中是在一个单元格&#xff0c;现在需要对其进行转换&#xff0c;将一个单元格换成多行 步骤&#xff1a; 1.删除换行符&#xff0c;添加一个逗号 2.选择数据-分列-分隔字符-逗号-确定 3.复制上述数据&#xff0c;选择性粘贴-转置 完…

2816. 判断子序列

题目链接&#xff1a; 自己的做法&#xff1a; #include <bits/stdc.h>using namespace std;const int N 1e5 10; int a[N], b[N]; int main() {int n, m;bool flag true;scanf("%d%d", &n, &m);for (int i 0; i < n; i) scanf("%d"…

哈希:探索快速的数据存储和搜索方法

哈希&#xff1a;探索快速的数据存储和搜索方法 哈希表作为一种高效的数据存储结构&#xff0c;可以使数据的存储位置与关键码之间建立一一映射的关系&#xff0c;从而加快元素的搜索速度。然而&#xff0c;哈希方法也面临着哈希冲突的问题&#xff0c;即不同的关键字通过相同…

dxf怎么转换成PDF格式?转换方法其实很简单

PDF文件是一种可靠的文件格式&#xff0c;可以在各种操作系统和软件上打开和查看。而dxf是CAD文件的一种格式&#xff0c;打开它一般都是需要相关的操作软件才能打开&#xff0c;不是特别方便&#xff0c;将dxf文件转换成PDF格式就可以很好的解决这一问题&#xff0c;下面教大家…

Kafka - Primie Number of Partitions Issue Consumer Group Rebalance

文章目录 生产者&#xff1a;将数据写入 Kafka 的客户端。 消费者&#xff1a;从 Kafka 中读取数据的客户端。 Topic&#xff1a;Kafka 中用于组织和存储数据的逻辑概念&#xff0c;类似于数据库表。 Record&#xff1a;发送到 Topic 的消息称为 Record。 Partition&#x…

List有值二次转换给其他对象报null

List<PlatformUsersData> listData platformUsersMapper.selectPlatformUserDataById(data); users.setPlatformUsersData(listData);为什么listData 有值&#xff0c;users.getPlatformUsersData&#xff08;&#xff09;仍然为空在这段代码中&#xff0c;我们假设listD…

NLP(六十)Baichuan-13B-Chat模型使用体验

2023年7月11日&#xff0c;百川智能正式发布参数量130亿的通用大语言模型Baichuan-13B-Base、对话模型Baichuan-13B-Chat及其INT4/INT8两个量化版本。   本文将介绍大模型BaiChuan-13B-Chat的使用体验&#xff0c;其HuggingFace网址为&#xff1a;https://huggingface.co/bai…

【团队协作开发】IDEA中Git新建自己的dev工作分支,合并到master主分支教程(极其简单,新手)

文章目录 一、创建新dev工作分支二、push到自己的远程dev工作分支三、工作分支合并到master主分支1、先切换到master主分支2、将远程工作dev分支的内容merge到当前master分支中3、将merge提交到远程master分支 一、创建新dev工作分支 创建完新dev分支以后将默认切换到新dev分支…

FFmpeg5.0源码阅读—— avcodec_send_frame avcodec_receive_packet

摘要&#xff1a;本文主要描述了FFmpeg中用于编码的接口的具体调用流程&#xff0c;详细描述了该接口被调用时所作的具体工作。   关键字&#xff1a;ffmpeg、avcodec_send_frame、avcodec_receive_packet   读者须知&#xff1a;读者需要了解FFmpeg的基本使用流程&#xf…

如何理解自动化

目录 1.如何定义自动化 2.自动化给人类带来的福利 3.如何学习自动化 4.自动化潜在的危害 1.如何定义自动化 自动化是指利用计算机、机械、电子技术和控制系统等现代科学技术手段&#xff0c;对各种工业、商业、农业和日常生活中的操作和过程进行自动控制和执行的过程。它旨在…

Vc - Qt - 自定义ComboBox

示例代码创建了一个名为ComboBoxWidget的自定义QWidget类&#xff0c;并在initUI方法中创建了一个垂直布局。然后将一个只读的QLineEdit和一个QPushButton添加到布局中。当按钮被点击时&#xff0c;会调用showMenu方法&#xff0c;该方法创建一个QMenu并添加选项。每个选项连接…

CodeForces:Madoka and Underground Competitions

经过观察&#xff0c;发现只要延小区域 右上-左下 的对角线填满X即可&#xff0c;那么就是可以总结为满足(i j) % k (r c) % k #include <bits/stdc.h> using namespace std; int t; void solve(){int n, k, r, c;cin >> n >> k >> r >> c…

什么是搜索引擎?2023 年搜索引擎如何运作?

目录 什么是搜索引擎&#xff1f;搜索引擎的原理什么是搜索引擎爬取&#xff1f;什么是搜索引擎索引&#xff1f;什么是搜索引擎检索?什么是搜索引擎排序&#xff1f; 搜索引擎的目的是什么&#xff1f;搜索引擎如何赚钱&#xff1f;搜索引擎如何建立索引?网页抓取文本处理建…

【C++基础(五)】类和对象(上)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C初阶之路⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 类和对象-上 1. 前言2. 类的引入3. 类的定义4. 类的…

【人工智能】深度优先搜索、代价一致搜索、深度有限搜索、迭代深度优先搜索、图搜索

【人工智能】无信息搜索—BFS 、代价一致、DFS、深度受限、迭代深入深度优先、图搜索 什么是搜索 搜索问题是指既不能通过数学建模解决,又没有其他算法可以套用或者非遍历所有情况才能得出正确结果。这时就需要采用搜索算法来解决问题。搜索就是一种通过穷举所有解的状态,来…