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,#0x40000000
	mov r1,#0xffffffff
	str r1,[r0] @将r1中的数据写一个字到0x40000000内存中
stop:
    b stop  
.end    

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

5. 寻址方式

(1. 前索引方式

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

在这里插入图片描述

在这里插入图片描述

(3. 自动索引

结合了前两者的索引方式

.text   
.global _start   
_start:
	mov r0,#0x40000000
	mov r1,#0xffffffff
	@自动索引方式 完成一次存储后r0寄存器会自动偏移8
	str 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,#1
	mov r2,#2
	mov r3,#3
	mov r4,#4
	mov r5,#5
	
	mov r6,#0x40000000
	stm 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,#1
	mov r2,#2
	mov r3,#3
	mov r4,#4
	mov r5,#5
	
	mov r6,#0x40000000
	stmia r6!,{r1-r5}
	
stop:
    b stop  
	
.end  

在这里插入图片描述

>2 ib后缀

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

.text   
.global _start   
_start:

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

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

>3 da后缀

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

.text   
.global _start   
_start:

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

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

>4 db后缀

db后缀:先偏移后存放

.text   
.global _start   
_start:

	mov r1,#1
	mov r2,#2
	mov r3,#3
	mov r4,#4
	mov r5,#5
	
	
	ldr r6,=0x40000800
	stmdb 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,#1
	mov r2,#2
	mov r3,#3
	mov r4,#4
	mov r5,#5
	
	
	ldr sp,=0x40000800 	@初始化栈
	stmdb sp!,{r1-r5}	@压栈用db
	ldmia sp!,{r7-r11}	@出栈用ia
	
stop:
    b stop  
	
.end  
======================================
采用满减栈特有后缀 "fd"
.text   
.global _start   
_start:

	mov r1,#1
	mov r2,#2
	mov r3,#3
	mov r4,#4
	mov r5,#5
	
	ldr sp,=0x40000800 	@初始化栈
	stmfd sp!,{r1-r5}	@压栈用db
	ldmfd sp!,{r7-r11}	@出栈用ia
	
stop:
    b stop  
	
.end  

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

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

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

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

.text   
.global _start   
    
_start:
    @栈的初始化
    LDR SP,=0X40000800
    b main
main:
    mov r1,#1
    mov r2,#2
    bl fun1
    add r3,r1,r2
    b main
fun1:
@ 压栈 保护现场,非叶子函数内部调用其他函数,lr的数值也会被覆盖,所以需要将它压栈保护
    stmfd sp!,{r1,r2,lr}
    mov r1,#5
    mov r2,#2
    bl fun2
    sub r4,r1,r2
    @出栈恢复现场
    ldmfd sp!,{r1,r2,pc}
    
    
fun2:
    @ 压栈 保护现场
    stmfd sp!,{r1,r2}
    mov r1,#6
    mov r2,#4
    mul 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,#0X10
    mov r1,#1
    mov r2,#2
    @触发软中断
    swi 1
    add r3,r1,r2
    b main
do_swi:
@压栈保护现场
    STMFD SP!,{R1,R2,LR}
    mov r1,#3
    mov r2,#5
    mul r4,r1,r2
    @恢复现场返回主程序执行
    LDMFD SP!,{R1,R2,PC}^   @^的作用是修改PC数值的同时将SPSR数值赋值给CPSR
stop:
    b stop   

.end   

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ELK(elasticsearch+logstash+kibana+beats)

什么是ELK Elasticsearch&#xff1a;Elasticsearch&#xff08;以下简称ES&#xff09; 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够解决不断涌现出的各种用例。 ES是 Elastic Stack 的核心&#xff0c;采用集中式数据存储&#xff0c;可以通过机器学习来…

Kubernetes_1.27.3_Harbor结合Nacos实战

Nacos 实战 作者:行癫(盗版必究) 一:Nacos简介 1.简介 ​ Nacos是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台;Nacos 致力于帮助您发现、配置和管理微服务;Nacos 提供了一组简单易用的特…

Python实现将pdf,docx,xls,doc,wps,zip,xlsx,ofd链接下载并将文件保存到本地

前言 本文是该专栏的第31篇,后面会持续分享python的各种干货知识,值得关注。 在工作上,尤其是在处理爬虫项目中,会遇到这样的需求。访问某个网页或者在采集某个页面的时候,正文部分含有docx,或pdf,或xls,或doc,或wps,或ofd,或xlsx,或zip等链接。需要你使用python自…

260道2023最新网络安全工程师面试题(附答案)

2023年过去了一大半&#xff0c;先来灵魂三连问&#xff0c;年初定的目标完成多少了&#xff1f;薪资涨了吗&#xff1f;女朋友找到了吗&#xff1f; ​好了&#xff0c;不扎大家的心了&#xff0c;接下来进入正文。 由于我之前写了不少网络安全技术相关的文章和回答&#xff…

CentOS 8 GLIBC升级失败系统崩溃抢修实战

CentOS 8 GLIBC升级失败系统崩溃抢修实战 1. 恐怖的问题2. 参考解决方案3. 抢修实战3.1 准备工作3.2 抢修流程3.3 解决启动后Permission Denied3.3.1 参考方案3.3.2 解决 4. 总结 服务器为CentOS 8&#xff0c;支持glibc版本为2.28&#xff0c;但编译一个工具的glibc需求版本为…

【Ceph集群应用】CephFS文件系统之MDS接口详解

CephFS文件系统之MDS接口详解 1.创建CephFS文件系统MDS接口1.1 创建cephfs1.2 基于内核的客户端挂载1.3 基于fuse工具方式的客户端挂载 接上文基于ceph-deploy部署Ceph集群详解 1.创建CephFS文件系统MDS接口 服务端操作 &#xff08;1&#xff09;在admin管理节点创建mds服务…

Python测试框架Pytest的基础入门

Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. 通过官方网站介绍…

音频数据分割单独处理后再拼接出现跳跃间断点的处理方法

+hezkz17进数字音频系统研究开发交流答疑 1如图所示 问题1: 对于一个81920字节的音频文件,如果是分割成小块4096输入(无重叠,均分),在频域上做去噪算法,每4k数据返回到时域上再拼接成80k的处理结果文件,发现处理结果有异常有跳跃间断点,像是频谱泄露?分割也需要有重…

java中使用POI生成Excel并导出

注&#xff1a;本文章中代码均为本地Demo版本&#xff0c;若后续代码更新将不会更新文章 需求说明及实现方式 根据从数据库查询出的数据&#xff0c;将其写入excel表并导出 我的想法是通过在实体属性上写自定义注解的方式去完成。因为我们在代码中可以通过反射的方式去获取实体…

华为申请注册盘古大模型商标;京东推出言犀大模型,率先布局产业应用

7月14日科技新闻早知道&#xff0c;一分钟速览。 1.华为申请注册盘古大模型商标&#xff1a; 据天眼查 App 显示&#xff0c;7 月 7 日&#xff0c;华为技术有限公司申请注册“华为云盘古”、“Huawei Cloud Pangu Models”文字及图形商标&#xff0c;国际分类为网站服务、社…

c基本数据类型

关键字 charshort intintlong intfloatdouble 常量和变量 常量&#xff1a;在程序运行过程中&#xff0c;其值不可改变的量变量&#xff1a;其值可以改变的量称为变量 字符数据 字符常量 直接常量&#xff1a;用单引号括起来&#xff0c;如&#xff1a;‘a’,‘b’.转义字…

zabbix 企业级监控(2) 监控linux主机

目录 配置开始 Zabbix添加linux主机 4.为agent.zabbix.com添加模板 环境&#xff1a; &#xff08;隔天做的更换了IP&#xff0c;不影响实际操作&#xff09; IP 192.168.50.50 关闭防火墙规则 更改主机名 [rootlocalhost ~]# vim /etc/hostname agent.zabbix.com [rootloca…

【UE5 多人联机教程】01-创建主界面

目录 工程地址 步骤 参考链接 工程地址 GitHub - UE4-Maple/C_MP_Lobby: 多人大厅教程项目 步骤 1. 先新建一个工程 2. 将下载的工程中的Plugins目录拷贝到自己新建的工程下 3. 打开工程&#xff0c;新建一个游戏实例 这里命名为“GI_Main” 在项目设置中设置游戏实例类为…

科技云报道:数字化转型完成后,制造业如何走向“数智”时代?

科技云报道原创。 随着我国数字化转型行动的深入推进和智能制造工程的大力实施&#xff0c;制造业正朝着“数智”时代迈进&#xff0c;生成式AI被视为推动制造业智能化发展的关键驱动力。 据预测&#xff0c;到2027年&#xff0c;将有30%的制造业采用生成式AI来提升产品研发效…

Android ViewGroup onDraw为什么没调用

ViewGroup&#xff0c;它本身并没有任何可画的东西&#xff0c;它是一个透明的控件&#xff0c;因些并不会触发onDraw&#xff0c;但是你现在给LinearLayout设置一个背景色&#xff0c;其实这个背景色不管你设置成什么颜色&#xff0c;系统会认为&#xff0c;这个LinearLayout上…

上海市静安区财政局领导带队调研合合信息,政企共话科技创新

近日&#xff0c;上海市静安区财政局副局长应文婷一行赴市北高新园区&#xff0c;实地走访科技企业上海合合信息科技股份有限公司&#xff08;简称“合合信息”&#xff09;&#xff0c;了解公司技术创新成果及产业布局&#xff0c;倾听企业在发展过程中的政策需求。合合信息董…

Linux——认识Linux的目录结构 常用命令 vim命令 权限及其控制

目录 linux的目录结构常用linux的命令ls(list)和llcd 切换目录mkdir 创建文件夹touch命令&#xff1a;创建普通文本文件pwd 显示路径whoamisu&#xff1a;普通--超级账号man&#xff1a;查看手册rm&#xff1a;删除网络命令ifconfig重定向 >>cat 查看文本文件clear清屏hi…

python使用Anconda安装Cartopy

安装 Cartopy的话官方推荐是使用conda安装&#xff0c;打开Anconda Prompt后&#xff0c;新建一个环境&#xff08;如果已有环境可跳过这步&#xff09;&#xff0c;然后激活环境&#xff1a; conda create -n newenv python3.9 conda activate newenv接着按照官网的推荐在Anc…

<数据结构>NO11.归并排序|递归|非递归|优化

文章目录 归并排序递归写法非递归写法修正方案1.归并一段拷贝一段修正方案2.修正区间 算法优化算法分析 归并排序的应用外排序和内排序 归并排序 递归写法 思路: 如果给出两个有序数组&#xff0c;我们很容易可以将它们合并为一个有序数组。因此当给出一个无序数组时&#xf…

【Ceph集群应用】Ceph块存储之RBD接口详解

Ceph块存储之RBD接口详解 1.创建Ceph块存储系统RBD接口1.1 删除镜像1.2 还原镜像1.3 在线扩容1.4 回滚镜像到指定位置1.5 删除快照1.6 快照分层1.7 快照展平1.8 镜像的导出导入 接上文基于ceph-deploy部署Ceph集群详解 1.创建Ceph块存储系统RBD接口 &#xff08;1&#xff09;…