stmdb:db(decrease before)表示先减后存。

指令 stmdb sp!, { fp, ip, lr, pc}  %% "!”表示sp等于最终被修改的sp的值。

假设 sp=4096,此条指令的执行过程如下:

1.先减:sp=sp-4=4092;

2.后存:4092-4095处存放pc的值;

3.先减:sp=sp-4=4088;

4.后存:4088-4091处存放lr寄存器的值;

以此类推,..........。

ldmia:ia(increase after)表示先读后增。

指令ldmia sp, {fp,sp, pc}

假设 sp=4080,此条指令的执行过程如下:

1.先读:fp位于4080-4083处存放原来保存的fp;

2.后增:sp=sp+4=4084;

3.先读:sp位于4084-4087处存放原来保存的ip;

4.后增:sp=sp+4;

以此类推,..........。

stm和ldm
    释义:
       stm:   (store much)多数据存储,将寄存器的值存到地址上
      ldm:   (load much)多数据加载,将地址上的值加载到寄存器上
    格式:
       ldm{cond}  mode  rn{!}, reglist{^}
       stm{cond} mode  rn{!}, reglist{^}
   详细释义:
       arm指令的多数据传输(stm、ldm)中,提到:多寄存器的load和store指令分为2组:
            一组用于数据的存储与读取(常用),对应于ia、ib、da、db 
              一组用于堆栈操作(基本用不到),对应于fd、ed、fa、ea,两组中对应的指令含义相同。

                即:
  
             stmib(地址先增而后完成操作)                   stmfa(满递增堆栈);
               stmia(完成操作而后地址递增)                   stmea(空递增堆栈);
               stmdb(地址先减而后完成操作)                  stmfd(满递减堆栈);
               stmda(完成操作而后地址递减)                  stmed(空递减堆栈)。
               上述各组2个指令含义相同只是适用场合不同,同理有:
               ldmib                                                 ldmed;
               ldmia                                                 ldmfd;
              ldmdb                                                ldmea;
               ldmda                                                 ldmfa。

               ia模式表示:每次传送后地址+4;(after increase)
               db模式表示:每次传送前地址-4;(before decrease)
               !   : 是选项,可有可无。加此选项,指令执行后,rn 的值会更新,等于下一个内存单元的地址
                 ^  : 如果reglist有pc寄存器,它表示指令执行后,spsr寄存器的值将自动复制到cpsr寄存器中
                                    —— 这常用于从中断处理函数中返回
                        如果reglis中没有 pc寄存器 , ^ 表示操作的是用户模式下的寄存器,而不是当前特权模式
                                   的寄 存器

stmdb和ldmia:
stmdb和ldmia指令一般配对使用,stmdb用于将寄存器存到某个地址上(一般是栈地址),ldmia用于将地址上
       的值加载到寄存器上,作用是保存使用到的寄存器。
  
举例一: 保存使用到的寄存器。
   将寄存器压栈(保存寄存器的值)
    指令:stmdb sp!,{r0-r12,lr}
    含义:sp = sp - 4,先压lr,[sp] = lr(即将lr中的内容放入sp所指的内存地址)。sp = sp - 4,再压r12,  
            [sp] = r12。sp = sp - 4,再压r11,[sp] = r11......sp = sp - 4,最后压r0,[sp] = r0。

寄存器弹出栈(恢复寄存器的值)
    指令:ldmia sp!,{r0-r12,lr}
    含义:r0 = [sp](sp地址处的值赋值给r0),sp = sp + 4,r1 = [sp],
              sp = sp + 4,r2 = [sp], sp = sp + 4,r3 = [sp]......最后lr = [sp]

详细分析:
    ldmia r0!,{r1-r4}
   r0:要操作的存储空间首地址,要操作的数据个数由寄存器列表决定,现在是r0到r4,共4个数据(每个数
          据32bit)
    具体:
   地址为r0的存储空间的数据赋值给r1
   地址为r0+4的存储空间的数据赋值给r2
   地址为r0+8的存储空间的数据赋值给r3
   地址为r0+12的存储空间的数据赋值给r4
    例:执行前:
   mem32[0x1000c] = 0x04
   mem32[0x10008] = 0x03
   mem32[0x10004] = 0x02
   mem32[0x10000] = 0x01
    r0 = 0x00010000
    r1 = 0x00000000
    r2 = 0x00000000
    r3 = 0x00000000
    r4 = 0x00000000
   执行后:存储空间不变,寄存器变化
    r0 = 0x00010000
    r1 = 0x01
    r2 = 0x02
    r3 = 0x03
    r4 = 0x04

举例二:
    stmia, 比如当前r0指向的内存地址是 0x1000,stmia r0!,{r1-r7} 就是 首先把r1存入 0x1000,然后r2
   存入0x1004,然后r3存入0x1008,如果是32位的处理器就是每次加4个字节,以此类推把 r1-r7按照递增、
   的地址存入,这个r0!就是从r0的地址开始存的意思。
   
   STMDB则是地址从r0开始减少,依次存储。

stmdb和ldmia相关推荐

  1. 【工程源码】stmdb和ldmia汇编指令

    本文由FPGA爱好者小梅哥编写,未经作者许可,本文仅允许网络论坛复制转载,且转载时请标明原作者. 首先一句话说一下stmdb和ldmia指令的作用: stmdb和ldmia指令一般配对使用,stmdb ...

  2. 37.Linux驱动调试-根据oops的栈信息,确定函数调用过程

    上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的 本章便通过栈信息来分析函数调用过程 1. ...

  3. cortex-m3 操作模式 寄存器组 异常类型 堆栈 中断

    cortex-m3 操作模式 寄存器组 异常类型 堆栈 中断 参考 操作模式 处理器的操作模式:为了区别正在执行代码的类型.复位后,处理器进入线程模式.特权级. 处理者模式(handler mode) ...

  4. cotex单片机寄存器(cm3为例)

     ARM单片机寄存器列表: 堆栈指针 R13   R13 是堆栈指针.在 CM3 处理器内核中共有两个堆栈指针,于是也就支持两个堆栈. 当引用 R13(或写作 SP)时,你引用到的是当前正在使用的那一 ...

  5. 寄存器(R0~R16)以及从SysTick系统时钟理解RTOS移植初始化

    移植系统最重要的细节之一就是配置系统时钟 第一次玩RT-Thread,发现同样的程序逻辑,测试现象不一样,从现象很明显看出来是时钟频率配置不一样. 由于之前玩STM32几乎没有关注过系统时钟的初始化, ...

  6. ARM base instruction -- ldm

    /*  * ldm  *  * 批量访问内存,内存中批量读取数据到寄存器  */ LDM|STM {type} 基址寄存器{!}, 寄存器列表{^} ldm{cond} {!} < regist ...

  7. LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA等指令详解

    关于多寄存器加载存储指令 1.LDMIA指令.LDMIB指令.LDMDB指令.LDMDA指令 (1)LDMIA指令,IA表示每次传送后地址加4 (2)LDMIB指令,每次传送前地址加四 (3)LDMD ...

  8. arm汇编指令探究之 ldmia

    ldmia r0!, {r4-r11, r14}  的意思是 LDMIA 中的 I 是 increase 的缩写,A 是 after 的缩写,LD加载(load)的意思 R0后面的感叹号"! ...

  9. 以SIGSEGV为例详解信号处理(与栈回溯)

    以SIGSEGV为例详解信号处理(与栈回溯) 信号是内核提供的向用户态进程发送信息的机制, 常见的有使用SIGUSR1唤醒用户进程执行子程序或发生段错误时使用SIGSEGV保存用户错误现场. 本文以S ...

最新文章

  1. 批处理+定时任务实现定时休息提醒
  2. 北大博士网恋被骗7400RMB,聊天记录惨遭曝光!
  3. [转]Hadoop家族学习路线图
  4. 修改Linux内核的printk缓冲区(log缓冲区)大小
  5. mysql 清理host文件_如何删除mysql 数据库里面的host
  6. 4计算准确率_PyTorch实现,GitHub 4000星:这是微软开源的计算机视觉库
  7. SAP Fiori Elements - how is read only field implemented in UI
  8. 24 React.createRef()用法细节分析
  9. 先弄个XML解析器代码抄一抄 慢慢研究 O(∩_∩)O哈哈~
  10. 【树链剖分】旅游(luogu 3976)
  11. c++可视化界面_新基建的福音:智慧楼宇可视化监控系统引领智能化新时代
  12. mysql优化有哪些着手点_mysql的优化总结
  13. docker安装启动mysql5.6_mysql5.6在ubuntu下的docker中安装的方法详解
  14. 洛谷P1087 FBI树
  15. 机器学习作业班_python实现支持向量机
  16. Java基础:JDK8新特性
  17. 复旦nlp实验室 nlp-beginner 任务二:基于深度学习的文本分类
  18. Flex Builder 中视图状态
  19. paraview编译
  20. iOS - Push 通知推送

热门文章

  1. android-4集成高德地图的搜索和导航功能
  2. css3 动画还原,CSS3animation动画-案例人物走路动画:(三)
  3. weka的java环境配置_weka学习(安装和部署)
  4. 数字电子技术基础——第三章 集成逻辑门电路
  5. Python:实现测试信用卡号码有效性credit card validator的算法(附完整源码)
  6. android 程序分身,Android应用分身检测
  7. Swift 编程语言入门教程
  8. 10大开源的快速开发平台
  9. Win10安装安卓模拟器入坑记
  10. 如何高效的远程办公(在家办公)