LDM批量加载/STM批量存储指令可以实现一组寄存器和一块连续的内存单元之间传输数据

允许一条指令传送16个寄存器的任意子集和所有寄存器,指令格式如下:
LDM{cond}  mode  Rn{!}, reglist{^}
STM{cond}  mode  Rn{!}, reglist{^}
主要用途:现场保护、数据复制、参数传送等,共有8中模式(前面4种用于数据块的传输,后面4种是堆栈操作)如下:
(1)IA:每次传送后地址加4
(2)IB:每次传送前地址加4
(3)DA:每次传送后地址减4
(4)DB:每次传送前地址减4
(5)FD:满递减堆栈
(6)ED:空递减堆栈
(7)FA:满递增堆栈
(8)EA:空递增堆栈
其中:
Rn:基址寄存器,装有传送数据的起始地址,Rn不允许为R15;
!:表示最后的地址写回到Rn中;
reglist:可包含多于一个寄存器范围,用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大顺序排列;
^:不允许在用户模式和系统模式下运行
 
根据ATPCS规则,我们一般使用FD(Full Descending)类型的数据栈!所以经常使用的指令就有STMFD和LDMFD,
通过ARM对于栈操作和批量Load/Store指令寻址方式,可以知道指令STMFD和LDMFD的地址计算方法:
STMFD指令的寻址方式为事前递减方式(DB)
 而DB寻址方式实际内存地址为:
 start_address = Rn - (Number_Of_Set_Bits_In(register_list)*4)
 end_address = Rn - 4
 STM指令操作的伪代码:
  if ConditionPassed(cond) then
     address = start_address
     for i = 0 to 15
         if register_list[i] == 1
              Memory[address] = Ri
              address = address + 4
有上面两个伪代码可以得出 STMFD SP!,{R0-R7,LR} 的伪代码如下:
   SP = SP - 9×4;
  address = SP; 
 for i = 0 to 7
    Memory[address] = Ri;
    address  = address + 4;
Memory[address] = LR;
由于ARM堆栈结构是从高向低压栈的,此时SP即是栈顶。因为处理器是32位的ARM,所以每次压一次栈SP就会移动4个字节(32位)。
蓝色标注的SP为执行指令前的SP地址,红色标注的SP是执行指令后的SP地址,由此看出STMFD指令是向下压栈的。
 
LDMFD指令的寻址方式为事后递增方式(IA)
IA内存的实际地址的伪代码
 start_address = Rn
 end_address = Rn + (Number_of_set_bits_in(register_list)*4) - 4
LDM指令操作的伪代码(未考虑PC寄存器):
  if ConditionPassed(cond) then
     address = start_address
     for i = 0 to 15
         if register_list[i] == 1
              Ri = Memory[address,4]
              address = address + 4
所以LDMFD SP!,{R0-R7,PC}^ (;恢复现场,异常处理返回)伪代码是:
  address = SP;
  for i = 0 to 7
     Ri = Memory[address ,4]
    address = address + 4;
  SP = address;
蓝色标注的SP为执行指令前的SP地址,红色标注的SP是执行指令后的SP地址。

LDM和STM指令的更多相关文章

  1. LDM与STM指令详解

    title: LDM与STM指令详解 date: 2019/2/26 17:58:00 toc: true --- LDM与STM指令详解 指令形式如下,这里的存储方向是针对寄存器的 Load Mul ...

  2. ARM LDR/STR, LDM/STM 指令

    这里比较下容易混淆的四条指令,已经在这4条指令的混淆上花费了很多精力,现在做个小结,LDR,STR,LDM,STM这四条指令, 关于LDM和STM的说明,见另外一个说明文件,说明了这两个文件用于栈操作 ...

  3. 汇编指令:ldr和str,ldm和stm的区别

    (1)LDR:L表示LOAD,LOAD的含义应该理解为:Load from memory into register.下面这条语句就说明的很清楚: LDR   R1,     [R2] R1<— ...

  4. ARM指令和Thumb指令区别

    Thumb指令集 ]的问题而提出的,它具有16为的代码密度.Thumb不是一个完整的体系结构,不能指望处理程序只执行Thumb指令而不支持ARM指令集.因此,Thumb指令只需要支持通用功能,必要时, ...

  5. X86架构与ARM架构比较(摘录自网络)

    引言 CPU是怎样运作的? CPU的运作与人脑的运作差不多.先谈一下人这个系统的工作方式.眼镜.耳朵.舌头.皮肤等等感觉器官接收到"触觉",把信息传给大脑,大脑把信息处理后,把处理 ...

  6. X86架构与ARM架构比较

    引言 CPU是怎样运作的? CPU的运作与人脑的运作差不多.先谈一下人这个系统的工作方式.眼镜.耳朵.舌头.皮肤等等感觉器官接收到“触觉”,把信息传给大脑,大脑把信息处理后,把处理结果送给手.脚.嘴等 ...

  7. LDMFD和STMFD个人理解

    ARM里面的堆栈是满递减(FULL DESCENDING)的.SP指向最后一个入栈的数据,SP的地址由高向低生长.对于LDM和STM指令来说,编号小的寄存器对应堆栈中的低地址. STMFD的寻址方式是 ...

  8. 大脸猫讲逆向之ARM汇编中PC寄存器详解

    i春秋作家:v4ever 近日,在研究一些开源native层hook方案的实现方式,并据此对ARM汇编层中容易出问题的一些地方做了整理,以便后来人能有从中有所收获并应用于现实问题中.当然,文中许多介绍 ...

  9. 常用 ARM 指令集及汇编

    ARM7TDMI(-S)指令集及汇编 ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 T ...

随机推荐

  1. VPython—旋转坐标系

    使用arrow( )创建三个坐标轴代表一个坐标系,其中X0-Y0-Z0为参考坐标系(固定不动),X-Y-Z为运动坐标系,这两个坐标系原点重合,运动坐标系可以绕参考坐标系或其自身旋转.在屏幕上输出一个转 ...

  2. Map Columns From Different Tables and Create Insert and Update Statements in Oracle Forms

    This is one of my most needed tool to create Insert and Update statements using select or alias from ...

  3. 基于ADL5317的雪崩光电二极管(APD)偏压控制/光功率监测电路的设计

    1 引言 目前,雪崩光电二极管(APD)作为一种高灵敏.能精确接收数据和测量光功率的光探测器件广泛应用于光纤传感.光纤通信网络中.它借助于内部强电场作用产生雪崩倍增效应,具有极高的内部增益(可达102 ...

  4. CUBRID学习笔记 10 数据库文件的类型和含义

    demodb contains the database data; demodb_lgar000, 001 and so forth are log archives used for point ...

  5. Android 布局简要范例

    Android的布局决定着实际的UI界面呈现情况,正是这些UI界面的组合与千变万化,才呈现出了各式各样的风格. 而这些基础的布局框架结构很重要,需要玩的很熟悉.我将以前参考的部分代码示例,所做的相关实 ...

  6. T-SQL Apply的用法

    SQL Server 2005 新增 cross apply 和 outer apply 联接语句,增加这两个东东有啥作用呢? 我们知道有个 SQL Server 2000 中有个 cross joi ...

  7. iOS - Swift NSTimeZone 时区

    前言 public class NSTimeZone : NSObject, NSCopying, NSSecureCoding NSTimeZone 表示时区信息. 1.NSTimeZone 时区的 ...

  8. c++ string的实现。

    第三次做了.只是做个复习.偶然发现之前的版本有内存泄露.基本功还是不过关.这次应该没有内存泄漏了.虽然是个简单版本. 1)了解堆,栈,值copy. 2)几个常用的c的字符函数和c中的char 如何表示 ...

  9. Team Formation

    #include <stdio.h> #include <ctype.h> #include <math.h> #include <stack> #in ...

  10. [转载] 使用异步 I/O 大大提高应用程序的性能

    原文: http://www.ibm.com/developerworks/cn/linux/l-async/ Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出 ...