Linux 学习记录53(ARM篇)

news2024/11/25 6:46:36

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   

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

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

相关文章

【论文学习】Distortion Agnostic Deep Watermarking

一、前言 论文链接&#xff1a;Distortion Agnostic Deep Watermarking 论文主要内容&#xff1a; 该文献提出了一种失真不可知的鲁棒水印模型&#xff0c;以解决现有DNN鲁棒水印方法的局限性。现有的DNN鲁棒水印方法&#xff0c;通常是在训练阶段将各类失真&#xff08;例如…

Databend 开源周报第 102 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 为指定列创建 B…

DataTable数据对比

DataTable数据对比 文章目录 DataTable数据对比前言一、计算DataTable差集结构不同的情况结构相同的情况 二、计算DataTable交集结构不同的情况结构相同的情况 三、计算DataTable的并集合两个DaTable结构相同的情况计算并集 前言 开发中我们经常会出现查询数据库后返回DataTab…

Spring Data JPA使用规则和审计的学习

一、引入依赖 完整的pom文件如下所示: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

idea 常用快捷键总结

IDEA常用快捷键总结 很多新手小白在使用IDEA进行代码编写的时候 对快捷键很感兴趣 这里泡泡给大家总结了一些常用的快捷键 希望能帮助到你 记得要收藏下来时常观看并且练习&#xff0c;才能熟练哦~ 1. 根据psvm或者main快速生成主函数 我们可以在类中输入psvm 或者main 然后I…

数据结构day4(2023.7.18)

一、Xmind整理&#xff1a; 链表的插入和删除&#xff1a; 二、课上练习&#xff1a; 练习1&#xff1a;顺序表去重 33 22 22 11 11 i jfor(int i0;i<list->len-1;i){for(int ji1;j<len;j){if(list->data[i]list->data[j]){delete_by_sub(j,list); …

springmvc @RequestMapping注解中produces以及consumes属性的含义(转载请删除括号里的内容)

http协议基础知识 首先需要了解什么叫MediaType&#xff08;媒体类型&#xff09;&#xff1f; 通俗来说&#xff0c;在http协议中&#xff0c;用来表示传输内容的格式就是MediaType&#xff0c;比如text/html&#xff0c;application/json等&#xff0c;其中text代表介质&am…

win7系统电脑怎么在桌面上悬挂工作日程安排清单显示呢?

在现代快节奏的工作环境中&#xff0c;合理安排和管理工作日程是非常重要的。而在电脑桌面上悬挂工作日程安排清单显示&#xff0c;可以让我们随时了解自己的任务和工作进度&#xff0c;提高工作效率。那么&#xff0c;如何在Win7系统电脑上实现这一功能呢&#xff1f; 今天我…

第六章内存保护单元(Cortex-M7 Processor)

目录 第六章内存保护单元 6.1关于MPU 6.2MPU功能描述 6.3MPU编程器模型 第六章内存保护单元 介绍MPU (Memory Protection Unit)。它包含以下部分: 关于第6-2页的MPU。MPU功能描述见第6-3页。MPU程序员模型在第6-4页。 6.1关于MPU MPU是内存保护的可选组件。处理器支持标准…

【算法基础:数据结构】2.3 并查集

文章目录 并查集算法原理&#xff08;重要&#xff01;⭐&#xff09; 经典例题836. 合并集合&#xff08;重要&#xff01;模板&#xff01;⭐&#xff09;837. 连通块中点的数量&#xff08;维护连通块大小的并查集&#xff09;240. 食物链&#xff08;维护额外信息的并查集&…

【Spring | 应用上下文】

应用上下文 应用上下文和资源路径构造应用上下文构造ClassPathXmlApplicationContext实例 — 快捷方式使用通配符蚂蚁式图案类路径&#xff1a;前缀 应用上下文和资源路径 本节介绍如何使用资源创建应用程序上下文&#xff0c;包括使用 XML 的快捷方式、如何使用通配符以及其…

能耗管理平台保障用电的安全

安科瑞虞佳豪 壹捌柒陆壹伍玖玖零玖叁 6月12日&#xff0c;江苏盐城射阳县某民房起火&#xff0c;消防救援人员到场后&#xff0c;立即对火势进行扑救&#xff0c;经过20多分钟的处置&#xff0c;现场明火全部被扑灭&#xff0c;据了解&#xff0c;起火原因是电线老化短路引发…

Mac下makefile使用openssl库

程序报错 ./polipo.h:208:10: fatal error: openssl/ssl.h file not found 安装和查找openssl开发库 brew install brew --prefix openssl cd /opt/homebrew/opt/openssl3 cd lib cd pkgconfig 通过makefile配置include文件和lib文件 pkg-config方式 lib文件查找&#xf…

C# 同构字符串

205 同构字符串 给定两个字符串 s 和 t &#xff0c;判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t &#xff0c;那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符&#xff0c;同时不改变字符的顺序。不同字符不能映射到同一个字符…

Mysql教程(五):DQL学习

Mysql教程&#xff08;五&#xff09;&#xff1a;DQL学习 DQL Data Query Language 数据查询语言&#xff0c;用来查询数据库中表的记录 1 基本语法 DQL查询语句&#xff0c;语法结构如下&#xff1a; SELECT字段列表 FROM表名列表 WHERE条件列表 GROUP BY分组字段列表 HAVI…

工时管理为何对项目如此重要?8Manage 带你读懂!

“时间就是金钱”&#xff0c;相信作为管理者都已经听腻了这话&#xff0c;但在项目管理中确实是真理。你要知道项目工时是会直接影响到项目费用成本的&#xff0c;不论项目工作是按小时还是按固定费用计费和付款&#xff0c;在一段工时内完成的工作越多&#xff0c;说明效率就…

myAgv的slam算法学习以及动态避障下篇

引言 在之前的一篇文章中有提到购入了一台myAGV&#xff0c;以树莓派4B为控制核心的移动机器人。上篇文章中向大家介绍了myAGV如何实现建图、导航以及静态避障&#xff0c;但我们深知&#xff0c;这只是机器人自主导航能力的基础。在实际应用场景中&#xff0c;机器人需要面对复…

【个人笔记】linux命令之ls

目录 Linux中一切皆文件ls命令常用参数常用命令lscpu lspci Linux中一切皆文件 理解参考&#xff1a;为什么说&#xff1a;Linux中一切皆文件&#xff1f; ls命令 ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于显示指定工作目录下之内容…

宝塔 30分钟部署免费在线客服系统

客服系统发布以来&#xff0c;一直有朋友询问如何在宝塔面板中安装部署&#xff0c;开始我一直认为参考 Linux 版的安装教程就可以了&#xff0c;一直没有专门写宝塔环境的教程。这段时间来咨询的朋友越来越多&#xff0c;经过了解&#xff0c;我才知道宝塔面板的普及率有多高&…

什么是Spring Actuator?它有什么优势?

目录 一、什么是Spring Actuator 二、Spring Actuator的应用场景 三、Spring Actuator的优势 一、什么是Spring Actuator Spring Actuator是Spring Boot提供的一个功能强大的管理和监控工具&#xff0c;用于监控和管理Spring Boot应用程序。它可以提供对应用程序的运行时信…