LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA指令详解
简介:
ARM指令中多数据传输共有两种:
LDM:(load much)多数据加载,将地址上的值加载到寄存器上
STM:(store much)多数据存储,将寄存器的值存到地址上
主要用途:现场保护、数据复制、参数传送等,共有8种模式(前面4种用于数据块的传输,后面4种是堆栈操作)如下:
(1)IA:(Increase After) 每次传送后地址加4,其中的寄存器从左到右执行,例如:STMIA R0,{R1,LR} 先存R1,再存LR
(2)IB:(Increase Before)每次传送前地址加4,同上
(3)DA:(Decrease After)每次传送后地址减4,其中的寄存器从右到左执行,例如:STMDA R0,{R1,LR} 先存LR,再存R1
(4)DB:(Decrease Before)每次传送前地址减4,同上
(5)FD: 满递减堆栈 (每次传送前地址减4)
(6)FA: 满递增堆栈 (每次传送后地址减4)
(7)ED: 空递减堆栈 (每次传送前地址加4)
(8)EA: 空递增堆栈 (每次传送后地址加4)
注意:其中在数据块的传输中是STMMDB和LDMIA对应,STMMIA和LDMDB对应
而在堆栈操作是STMFD和LDMFD对应,STMFA和LDMFA对应
格式:
LDM{cond} mode Rn{!}, reglist{^}
STM{cond} mode Rn{!}, reglist{^}
其中
Rn:基址寄存器,装有传送数据的起始地址,Rn不允许为R15;
!:表示最后的地址写回到Rn中;
reglist:可包含多于一个寄存器范围,用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大顺序排列;
^:不允许在用户模式和系统模式下运行
数据块的传输-实例:
Ldr R1,=0x10000000 //传送数据的起始地址0x10000000
LDMIB R1!,{R0,R4-R6} //从左到右加载,相当于 LDR R0,10000004 LDR R4,10000008... ...
/*传送前地址加+4,
所以地址加4,R0=0X1000004地址里的内容,
地址加4,R4=0X10000008地址里的内容,
地址加4,R5=0X1000000C地址里的内容,
地址加4,R6=0X10000010 地址里的内容,
由于!, 最后的地址写回到R1中,R1=0X10000010 */
Ldr R1,=0x10000000 //传送数据的起始地址0x10000000
LDMIA R1!,{R0,R4-R6} //从左到右加载,相当于 LDR R0,10000000 LDR R4,10000004... ...
/*传送后地址加+4,
所以R0=0X10000000地址里的内容,地址加4,
R4=0X10000004地址里的内容,地址加4,
R5=0X10000008地址里的内容,地址加4,
R6=0X1000000C 地址里的内容,地址加4,
由于!,最后的地址写回到R1中,所以R1=0X10000010 */
LDR R1,=0x10000000 //传送数据的起始地址0x10000000
LDR R4,=0X10
LDR R5,=0X20
LDR R6,=0X30
STMIB R1,{R4-R6} //从左到右加载,相当于STR [R4],0X10000004 STR [R5],0X10000008 .....
/*传送前地址加+4,所以0X10000004地址=0X10,0X10000008地址=0X20,0X1000000C地址=0X30 */
Ldr R1,=0x10000000 //传送数据的起始地址0x10000000
LDR R4,=0X10
LDR R5,=0X20
LDR R6,=0X30
STMIA R1!,{R4-R6 }
/*传送后地址加+4,所以0X10000000地址=0X10,0X10000004地址=0X20,0X10000008地址=0X30,由于!,最后的地址写回到R1中,所以R1=0X1000000C */
中断实例(利用STMDB和LDMIA保护现场,然后通过LR寄存器返回)
1.先设置栈sp,用于后面使用stmdb存储寄存器数据
2.当产生异常时,便进入中断:
sub lr, lr, #4
//首先将lr-4,因为arm流水线,lr=当前pc+8,由于pc+4段没有执行,所以lr=(当前pc+8)-4;
stmdb sp!, { r0-r12,lr }
//每次传送前-4,且从右往左存储寄存器
//所以sp-4=lr,sp-8=r12,... sp-56=r0; 由于!,所以最后的地址写回到sp中,sp=sp-56;
ldr lr, =int_return //设置返回地址
ldr pc, =EINT_Handle //进入中断服务函数,如果中途返回就会调用pc=lr,即可执行int_return;
int_return:
ldmia sp!, { r0-r12,pc }^
//每次传送后+4,且从左往右加载数据到寄存器
//所以r0=sp, r1=sp+4,...pc=sp+52;由于!,所以最后地址写回到sp中,sp=sp+56;
//此时,sp=sp+56就等于最初栈顶值,pc=lr,然后返回到异常发生前的相应位置继续执行。
//^ ^表示将spsr的值复制到cpsr,因为异常返回后需要恢复异常发生前的工作状态
LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA指令详解的更多相关文章
- ARM v7汇编与相关练习
程序入口: _startc 语言入口: main@: 注释;main: 标签;伪指令: 给汇编器读的指令;.global main ...
- ARM汇编指令-STMFD/LDMFD
根据调用规则ATPCS,程序一般都使用FD(FullDescending)类型的数据栈(满栈),那么对立的就由空栈类型的数据栈.空栈是指SP操作完后指向的地址空间是未使用的,反之满栈就是SP指向的地址 ...
- ARM指令系统
转载自:http://cxb4224.blog.163.com/blog/static/191224151201110220325976/ ARM处理器的工作状态和工作模式 工作状态 ARM处理器一般 ...
- ARM-汇编指令集(总结)
ARM汇编指令集 指令.伪指令 (汇编)指令: 是机器码的助记符,经过汇编器编译后,由CPU执行. (汇编)伪指令:用来指导指令执行,是汇编器的产物,最终不会生成机器码. 有两种不同风格的ARM指 ...
- LDM与STM指令详解
title: LDM与STM指令详解 date: 2019/2/26 17:58:00 toc: true --- LDM与STM指令详解 指令形式如下,这里的存储方向是针对寄存器的 Load Mul ...
- [转]Whirlwind Tour of ARM Assembly
ref:http://www.coranac.com/tonc/text/asm.htm 23.1. Introduction Very broadly speaking, you can divid ...
- C函数调用
目录 C函数调用 设置SP SP分析 区分NAND和NOR启动 参数调用 title: C函数调用 tags: ARM date: 2018-10-14 16:37:10 --- C函数调用 设置SP ...
- STM32F4XX启动文件分析
STM32F4XX启动文件分析 - STM32F4XX启动文件下载地址 导读:STM32F4XX启动文件的作用 初始化设置SP,即栈指针 初始化设置PC指针指向复位中断处理函数,即PC = Reset ...
- 常用 ARM 指令集及汇编
ARM7TDMI(-S)指令集及汇编 ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 T ...
随机推荐
- Jetty的工作原理
Jetty的工作原理 Jetty 的基本架构 Jetty 目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器,它有一个基本数据模型,这个数据模型就 ...
- 起床困难综合症[NOI2014]
[题解] 并不算很困难的贪心题.位运算毕竟是针对每一位的,从前向后处理,如果某一位1比0更优且可取1就使它为1.比较0和1的结果要单取这一位来看,但是题目中所给的参数并没有必要全部二进制分解,直接用十 ...
- Javascript闭包与作用域this
闭包与this的一般用法 关于js函数与闭包的文章想必大家都是在熟悉不过的了,作为js核心亦即最强大的功能之一,每次回过头翻出来看一看,都会有不一样的收获与理解,经典的含义无非如此而已. 1.闭包 1 ...
- angular学习(五)-- Module
1.5 模块:Module 模块定义了一个应用程序 模块是应用程序中不同部分的容器 模块是应用控制器的容器 控制器通常属于一个模块 ng 中模块的引入最重要的目的就是为了解决原来全局定义的控制器污染的 ...
- python学习===判断两个日期的间距天数
import datetime d1 = datetime.date(2015,10,7) d2 = datetime.date(2015,8,15) print((d1-d2).days)
- python连接数据库异步存储
当同步写入数据库时,可能会发生下载速度很快,但是写入速度很慢的情况,因此我们采用异步存储写入数据库. 实现异步写入mysql数据库的思路: 1,将数据库的连接数据写入到settings文件中,供后面自 ...
- c++类大小问题
1.空类 class A { }; 解析:类的实例化就是为每个实例在内存中分配一块地址:每个类在内存中都有唯一的标识,因此空类被实例化时,编译器会隐含地为其添加一个字节,以作区分. 2.虚函数类 cl ...
- 齐博cms 7.0 漏洞分析
** 0x01 原理分析 ** 还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴: https://security.alibaba.com/... 漏洞发生在/inc/common.inc ...
- 高级映射,查询缓存和与spring整合
一.高级映射 -------一对一 这里以订单查询为例,其中有一个外键为user_id,通过这个关联用户表.这里要实现的功能是这个两个表关联查询,得到订单的信息和部分user的信息.order表结构如 ...
- JMeter安装和简介
1.Apache jmeter 是一个100%的纯java桌面应用,用于压力测试和性能测量.它最初被设计用于Web应用测试但后来扩展到其他测试领域,可以用于对静态的和动态的资源(文件,Servlet, ...