ARM的读写内存指令与栈的应用
1.基础读写指令
写内存指令:STR
@ MOV R1, #0xFF000000@ MOV R2, #0x40000000@ STR R1, [R2] @ 将R1寄存器中的数据写入到R2指向的内存空间
需注意,此命令是将R1中的数据写给R2所指向的内存空间,而不是直接把R1的数据赋给R2,R2寄存器中存放的是数据要被写入的内存的起始地址,由于使用的是STR指令,所以R2中存放的地址时不会改变的,如果后续再次向R2所指向的内存中写数据,则原来的数据会被覆盖。
读内存指令:LDR
@ MOV R1, #0xFF000000@ MOV R2, #0x40000000@ LDR R3, [R2]@ 将R2指向的内存空间中的数据读取到R3寄存器
原理基本同上,是将R2存放的地址指向的空间中的数据读取到R3寄存器中
读写指定的数据类型:
在ARM中有三种数据类型,Byte类型占一个字节,Halfword类型占两个字节,Word类型占四个字节,如果我们指向读取某个数据类型的数据,只需要在读写指令后加上后缀即可,示例如下:
@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@Byte类型:@ STRB R1, [R2]@ 因为Byte类型占一个字节也就是8bit,@所以指令的含义是将R1寄存器中的数据的前8位写入到R2指向的内存空间@Halfword类型:@ STRH R1, [R2] @ 将R1寄存器中的数据的前16位写入到R2指向的内存空间@Word类型:@ STR R1, [R2] @ 将R1寄存器中的数据的前32位写入到R2指向的内存空间@ LDR指令同样支持以上后缀,并且含义相同
2.基址加变址寻址:
前索引和后索引:
由其定义可知,我们要操作的地址变成了 基本地址 + 可变地址,如下程序所示,要进行读写操作的内存的地址变成了中括号中的数据的和。
@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ MOV R3, #4@ STR R1, [R2,R3]@ 将R1寄存器中的数据写入到R2+R3指向的内存空间,也就是0x40000004指向的地址空间@ STR R1, [R2,R3,LSL #1]@ 将R1寄存器中的数据写入到R2+(R3<<1)指向的内存空间
上面代码中将可变地址R3写入中括号里的方法叫做基址加变址寻址的前索引方式,而将其写在中括号后为后索引方式,他们俩的含义如下:
@ 前索引@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2,#8]@ 将R1寄存器中的数据写入到R2+8指向的内存空间@ 后索引@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2],#8@ 将R1寄存器中的数据写入到R2指向的内存空间,然后R2自增8
自动索引:
除了他们俩之外,还有一种索引叫做自动索引,其定义如下:
@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2,#8]!@ 将R1寄存器中的数据写入到R2+8指向的内存空间,然后R2自增8
需注意,自动索引! 的位置是不能改变的并且 必须要是英文的
3.多寄存器内存访问指令:
多寄存器内存访问指令,其含义就是同时读写多个寄存器中的数据,示例如下:
@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STM R11,{R1-R4}@ 将R1-R4寄存器中的数据写入到以R11为起始地址的内存空间中@ LDM R11,{R6-R9}@ 将以R11为起始地址的内存空间中的数据读取到R6-R9寄存器中
与单独读写一个寄存器的数据相比,指令由STR和LDR变成了STM和LDM,其存放 要进行读或写操作的地址 的寄存器变成了目标寄存器,也就是作为了指令后的第一个参数,要被读入或写的数据所要存放的寄存器被放在一个大括号中,ARM会依次将其读取或写入到相应的位置,大括号中的写法也可以使用逗号隔开,例如{R1,R2,R3,R4},但是无论其顺序怎么改变,他在进行操作时都是低地址对应小号的寄存器,例如上边程序的写指令即使写成 STM R11,{R2,R1,R4,R3} 他在写入到R11为起始地址的内存空间中时也是先将R1存放到底地址0x4000020当中,读指令也是如此。
自动索引也同样适用于多寄存器内存访问指令,只是感叹号位置发生了改变,具体如下:
@ STM R11!,{R1-R4}
执行完这条指令后,R1-R4会被依次写入在R11指向的地址处,因为写入了四个数据,所以R11所储存的地址会自增16个字节。
多寄存器内存访问指令的寻址方式:
STM指令与LDM指令有四个后缀,分别为IA,IB,DA,DB,下面的这些都是在其有自动索引时的解释,其意义分别为:
- STMIA R11! :先储存数据,然后地址在增加
- STMIB R11! : 地址先增加,然后再储存数据
- STMDA R11! :先储存数据,然后地址递减
- STMDB R11! :地址先减少,然后再储存数据
如下图所示,我用大白话形容一下,IA就是先把你要写入的第一条数据先写进R11存放的地址中,然后再将R11的地址增加去存放下一个数据,直到数据全部存完后R11的地址在增加一次指向写入的最后一个数据的下一个地址,IB就是先让R11的地址增加一次,然后再开始写入数据,最后R11的地址会指向所写入的最后一条数据。DA和DB只是存储方向相反而已,方式是相同的,注意写入数据和增加地址的过程是一一对应的,写一条就要加一次,数据是一条一条存放到内存中而不是一下全放进去然后地址一次性增加。
@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STMIA R11!,{R1-R4}@ 先存储数据,后增长地址@ STMIB R11!,{R1-R4}@ 先增长地址,后存储数据@ STMDA R11!,{R1-R4}@ 先存储数据,后递减地址@ STMDB R11!,{R1-R4}@ 先递减地址,后存储数据
ARM使用的大多是
4.ARM栈的种类与使用:
概念:栈的本质就是一段内存,程序运行时用于保存一些临时数据,如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等
栈的分类:
- 增栈:压栈时栈指针越来越大,出栈时栈指针越来越小
- 减栈:压栈时栈指针越来越大,出栈时栈指针越来越小
- 满栈:栈指针指向最后一次压入到栈中的数据,压栈时需要先移动栈指针到相邻位置然后再压栈
- 空栈:栈指针指向最后一次压入到栈中的数据的相邻位置,压栈时可直接压栈,之后需要将栈指针移动到相邻位置
增减和空满是组合在一起的,栈分为空增(EA)、空减(ED)、满增(FA)、满减(FD)四种,EA对应上面的IA,ED对应DA,FA对应IB,FD对应DB可以对应ARM处理器一般使用满减栈,所以对ARM的栈做存储操作时可以直接使用FD后缀
叶子函数:一个函数里没有调用其他函数,那么他就是叶子函数
汇编中进行跳转的过程就在下面代码中,程序自己理解吧,等哪天我在把具体的步骤写一下哈哈哈
示例:
@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STMFD R11!,{R1-R4}@ LDMFD R11!,{R6-R9}@ 栈的应用举例@ 1.叶子函数的调用过程举例@ 初始化栈指针@ MOV SP, #0x40000020
@ MIAN:@ MOV R1, #3@ MOV R2, #5@ BL FUNC@ ADD R3, R1, R2@ B STOP@ FUNC:@ 压栈保护现场@ STMFD SP!, {R1,R2}@ MOV R1, #10@ MOV R2, #20@ SUB R3, R2, R1@ 出栈恢复现场@ LDMFD SP!, {R1,R2}@ MOV PC, LR@ 2.非叶子函数的调用过程举例@ MOV SP, #0x40000020
@ MIAN:@ MOV R1, #3@ MOV R2, #5@ BL FUNC1@ ADD R3, R1, R2@ B STOP
@ FUNC1:@ STMFD SP!, {R1,R2,LR}@ MOV R1, #10@ MOV R2, #20@ BL FUNC2@ SUB R3, R2, R1@ LDMFD SP!, {R1,R2,LR}@ MOV PC, LR
@ FUNC2:@ STMFD SP!, {R1,R2}@ MOV R1, #7@ MOV R2, #8@ MUL R3, R1, R2@ LDMFD SP!, {R1,R2}@ MOV PC, LR@ 执行叶子函数时不需要对LR压栈保护,执行非叶子函数时需要对LR压栈保护
相关文章:
ARM的读写内存指令与栈的应用
1.基础读写指令 写内存指令:STR MOV R1, #0xFF000000 MOV R2, #0x40000000 STR R1, [R2] 将R1寄存器中的数据写入到R2指向的内存空间 需注意,此命令是将R1中的数据写给R2所指向的内存空间,而不是直接把R1的数据赋给R2,R2寄存器…...
2022年平均工资出炉,IT行业又是第一
根据5月9日国家统计局最新资料显示,2022年,全国城镇非私营单位就业人员年平均工资为114029元,比上年增长6.7%,扣除通胀后实际增长4.6%。其中,行业间的差距相当明显。根据资料显示,2022年无论是在私营单位还…...
ov2640子设备核心操作详细分析
ov2640子设备核心操作详细分析 文章目录 ov2640子设备核心操作详细分析ov2640_subdev_core_ops核心操作获取寄存器值ov2640_g_register设置寄存器值ov2640_s_registeri2c_smbus_xferi2c_imx_xferi2c_smbus_xfer_emulatedi2c_transfer__i2c_transfer 设置ov2640的电源ov2640_s_p…...
MATLAB语句实现方阵性质的验证
系列文章目录 MATLAB绘图函数的相关介绍——海底测量、二维与三维图形绘制 MATLAB求函数极限的简单介绍 matlab系统环境思维导图 文章目录 系列文章目录 1. MATLAB语句验证方阵的六个性质如下 2. 六个性质的解释如下 3. 使用随机矩阵进行验证的代码示例如下 总结 前言 …...
使用Springboot AOP进行请求接口异常监控
常用注解 Aspect 切面类 Before 前置 AfterReturning 后置 Around 环绕 AfterThrowing 异常 切入点设置 execution(public * *(..)) 定义任意公共方法的执行 execution(* set*(..)) 定义任何一个以"set"开始的方法的执行 execution(* com.sys.service.UserService…...
【云原生|Kubernetes】05-Pod的存储卷(Volume)
【云原生Kubernetes】05-Pod的存储卷(Volume) 文章目录 【云原生Kubernetes】05-Pod的存储卷(Volume)简介Volume类型解析emptyDirHostPathgcePersistentDiskNFSiscsiglusterfsceph其他volume 简介 Volume 是Pod 中能够被多个容器访问的共享目录。 Kubern…...
Python实现数据结构
文章目录 一、Python实现数据结构1.1 python实现单向链表1.2 python实现单向循环链表1.3 python实现双向链表 一、Python实现数据结构 1.1 python实现单向链表 singleLinkedList.py class SingleNode:"""the node of single link list"""def …...
esp32CAM环境安装教程---串口驱动安装
前言 (1)本人安装好arduino 的ESP32环境之后, 发现一直下载不进去程序。一直说Cannot configure port, something went wrong. Original message: PermissionError。 (2)查阅了很多资料,用了各种办法&#…...
Java中List和Array转换
文章目录 List -> Array1. 调用toArray()方法直接返回一个Object[]数组:2. 给toArray(T[])传入一个类型相同的Array,List内部自动把元素复制到传入的Array中:3. 通过List接口定义的T[] toArray(IntFunction<T[]> generator)方法&…...
如何能确定数据库中root用户的密码是什么
如果您无法确定数据库中 root 用户的密码,有几种方法可以尝试找回或重置密码: 1. 使用已知密码:如果您有之前设置的 root 用户密码,可以使用该密码进行登录。 2. 查找密码文件:在某些情况下,MariaDB 可能…...
由浅入深Netty协议设计与解析
目录 1 为什么需要协议?2 redis 协议举例3 http 协议举例4 自定义协议要素4.1 编解码器4.2 什么时候可以加 Sharable 1 为什么需要协议? TCP/IP 中消息传输基于流的方式,没有边界。 协议的目的就是划定消息的边界,制定通信双方要…...
iptables防火墙(1)
iptables防火墙 一、iptables概述二、netfilter/iptables 关系三、四表五链1.四表2.五链 四、规则链之间的匹配顺序五、规则链内的匹配顺序六、iptables安装与配置七、常用的控制类型八、常用的管理选项九、规则命令1.添加新规则2.查看规则列表3.设置默认策略4.删除规则5.清空规…...
第九章 Productions最佳实践 - Productions开发的最佳实践
文章目录 第九章 Productions最佳实践 - Productions开发的最佳实践Productions开发的最佳实践项目目标项目交付文档 第九章 Productions最佳实践 - Productions开发的最佳实践 Productions开发的最佳实践 本章是一个总体概述,旨在帮助团队成员为从事生产项目做好…...
RocketMQ 怎么实现的消息负载均衡以及怎么能够保证消息被顺序消费
一、RocketMQ 怎么实现的消息负载均衡 RocketMQ是一种开源的分布式消息中间件,它使用了一种称为消息负载均衡的机制来实现消息的分发和消费的负载均衡。RocketMQ的消息负载均衡主要是通过以下两个方面实现的: 消息队列分组(Message Queue G…...
【随笔记】全志 T507 PF4 引脚无法被正常设置为中断模式的问题分析
相关信息 硬件平台:全志T507 系统版本:Android 10 / Linux 4.9.170 问题描述:PF4 无法通过标准接口设置为中断模式,而 PF1、PF2、PF3、PF5 正常可用。 分析过程 一开始以为是引脚被其它驱动占用引起,或者该引脚不具…...
人手一个 Midjourney,StableStudio 重磅开源!
人手一个 Midjourney,StableStudio 重磅开源! Stability AI 公司在上个月 19 号推出了 Alpha 版本 StableLM 大语言模型,包含了 30 亿和 70 亿参数,并且支持商用。如今他们再次推出了 AI 图像生成平台 StableStudio,这…...
iptables防火墙(2)
iptables防火墙(2) 一、SNATSNAT应用环境SNAT原理SNAT转换前条件扩展 二、DNATDNAT应用环境DNAT原理DNAT转换前提条件扩展 三、防火墙规则的备份和还原导出(备份)所有表的规则导入(还原)规则 一、SNAT SNA…...
Windows和Kali上使用proxychains代理流量
Windows和Kali上使用proxychains代理流量 PS. 本文演示都是在kali进行的,如有出入还请联系我哦1. Linux(Debian)1.1. 检查一下是否有proxychains1.2 修改config文件 2. Linux(Debian)安装proxychians43. Windows3.1 下载3.2 配置 4. Windows下的配置5. 测试 PS. 写这…...
KEYSIGHT MSOS204A 2GHZ 4通道DSOS204A高清晰度示波器
KEYSIGHT是德DSOS204A/MSOS204A高清晰度示波器 附加功能: 2 GHz 带宽(可升级) 4 个模拟通道和 16 个数字通道 最大存储深度:800 Mpts(2 通道),400 Mpts(4 通道) 最大…...
最新Java适配商城系统
城前端功能展示 商城移动端 后端基于SpringBoot 研发,前端使用 Vue、uniapp开发 前后端分离,支持分布式部署,支持Docker,各个API独立,并且有独立的消费者 api不需要单独部署,只需启动一个jar包就可以正…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
