1.LDRL表示LOAD

理解为:Load from memory into register。

LDR   R1,     [R2]

R1【寄存器】<——[R2]【内存RAM】

将R2的memory内容copy到R1寄存器.

2.STRS表示STORE

理解为:Store from a register into memory.

STR    R1,     [R2]

R1【寄存器】——>[R2]内存RAM】

将R1寄存器内容copy到R2的memory.

(3)LDML的含义仍然是LOAD(连接寄存器和连续内存的相互copy)

理解为:Load from memory into register。

虽然貌似是LDR的升级,但是,千万要注意,这个指令运行的方向和LDR是不一样的,是从左到右运行的。该指令是将内存中堆栈内的数据,批量的赋值给寄存器,即是出栈操作;其中堆栈指针一般对应于SP,注意SP是寄存器R13,实际用到的却是R13中的内存地址,只是该指令没有写为[R13],同时,LDM指令中寄存器和内存地址的位置相对于前面两条指令改变了,下面的例子:

LDMFD     SP! ,   {R0, R1, R2}

实际上可以理解为:    LDMFD     [SP]!,    {R0, R1, R2}

意思为:把sp指向的3个连续地址段(应该是3*4=12字节(因为为r0,r1,r2都是32位))中的数据拷贝到r0,r1,r2这3个寄存器中去(如果这个地方还不懂的话,可以参看我文章开头提到的链接,里面有详细的图解)

(4)STMS的含义仍然是STORE,与LDM是配对使用的,其指令格式上也相似,即区别于STR,是将堆栈指针写在左边,而把寄存器组写在右边。

 STMFD      SP!,   {R0}

同样的,该指令也可理解为:  STMFD      [SP]!,   {R0}

意思是:把R0保存到堆栈(sp指向的地址)中。

显然,这两个堆栈操作指令也有个特点,就是寄存器组写在后面(右边)而堆栈指针写在前面(左边),而且实际上使用的是堆栈指针中的内存地址,这一点与前面两条指令是有区别的。

(补充:sp后面的!,作用是指命令执行完后,对应的地址值赋给sp,对于例程的SDM,是说最后sp的值应该是sp+3*4=sp+12)

1.volatile.c
#include <stdio.h>
int main (void){    volatile int i = 35;int a = i;
}

# aarch64-linux-gnu-gcc  asm_volatile.c -S -O2 -o volatile.s

//volatile.s.arch armv8-a.file   "asm_volatile.c".text.section .text.startup,"ax",@progbits.align   2.p2align 3,,7.global   main.type   main, %function //以.开头的都是外代码标签.
main:sub    sp, sp, #16   //sp = sp -16 ;栈从高地址到低地址,分配16个字节栈空间,等待输入入栈.mov w0, 35       //将立即数35存入寄存器w0str w0, [sp, 12] //将w0寄存器中的值存到sp+12所指定的地址内存;store register[w0] to memory[sp,12].mov    w0, 0        //置空w0寄存器.ldr  w1, [sp, 12] //将(sp+12)地址内存中的内容存到w1寄存器;load memory[sp,12] to register[w1].add  sp, sp, 16   //sp = sp + 16;//栈从高地址到低地址,恢复16字节地址,sp指针重新指向sp+16地址ret.size main, .-main.ident  "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0".section .note.GNU-stack,"",@progbitsstr理解为:  store a register to memorystr w0, [sp,12]
w0: register
[sp,12]: memoryldr理解为:  load  memory  to a register
ldr w1, [sp,12]
w1: register
[sp,12]: memorystm :store multi registers to some memory
ldm: load multi registers from some memory
2.optimize.c
#include <stdio.h>
int main (void){    int i = 20;int a = i;
}

# aarch64-linux-gnu-gcc  asm_optimize.c -S -O2 -o optimize.s

 .arch armv8-a.file  "asm_optimize.c".text.section .text.startup,"ax",@progbits.align   2.p2align 3,,7.global   main.type   main, %function
main:mov    w0, 0ret.size   main, .-main.ident  "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0".section .note.GNU-stack,"",@progbits

ARM指令ldr、str、stm、ldm理解相关推荐

  1. 汇编指令ldr str stm ldm

    ldr命令:把数据从内存加载到寄存器 ldr r0, =addr ;r0 = addr ldr r1, [r0] ; r1 = *r0 ldr r1, [r0, #4] ; r1 = *(r0+4) ...

  2. ARM 指令 LDR

    LDR的格式 LDR{条件}   目的寄存器     <存储器地址> 作用:将 存储器地址 所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中. LDR Rn, label1 LD ...

  3. ARM指令 LDR 和 ADR的一些区别

    LDR 是ARM中的指令,也是伪指令. 当用 LDR r, =imd  // r 为寄存器, imd为立即数 LDR 是一条伪指令.编译器会根据 立即数的大小,决定用 ldr 指令或者是mov或mvn ...

  4. 汇编指令的学习2——常用的ARM指令

    一.常用ARM指令1:数据处理指令 (1)数据传输指令 mov mvn(源目标按位取反后赋给目标) (2)算术指令 add sub rsb adc sbc rsc (3)逻辑指令 and orr eo ...

  5. 汇编指令mrs_专题1:电子工程师 之 软件】 之 【8.arm指令】

    希望本是无所谓有,无所谓无的,这正如脚下的路,其实地上本没有路,走的人多了,也便成了路....原创不易,文章会持续更新,感谢您的关注 1.伪指令和指令之间的差别 指令是CPU机器码的助记符,它经过编译 ...

  6. 关于汇编指令ldr和str的理解

    (1)..ldr指令:(load装载) 外存--->>>内存 ldr 指令传数据(将数据传入寄存器) 无论是否是立即数,都可以进行传 格式:ldr 寄存器,=数字 若数字式立即数:l ...

  7. 汇编指令的学习4——ldm/stm指令、栈的处理

    1.为什么需要多寄存器访问指令? ldr/str每周期只能访问4字节内存,如果需要批量读取.写入内存时太慢,解决方案是stm/ldm ldm  (load register mutiple) stm( ...

  8. LDR/STR指令学习

    S3C2440A datasheet上关于这两条指令的说明如下: SINGLE DATA TRANSFER (LDR, STR), The single data transfer instructi ...

  9. arm指令中mov和ldr及ldr伪指令的区别

    ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令.比如想把数据从内存中某处读取到寄存器中,只能使用ldr比如:ldr r0, 0x12345678就 ...

最新文章

  1. codeforces 165B(Burning Midnight Oil)
  2. 【冷知识】获取网页所有的监听事件类型、方法。请认准getEventListeners
  3. 在Windows系统上安装Ruby On Rails
  4. memory matlab,memory – 在MATLAB中处理大量结构
  5. python导入模块
  6. 第一个shell脚本
  7. 分布式事务 - 如何解决分布式事务问题?
  8. 【5岁小孩对唱情歌 超萌超可爱】
  9. linux kill 子进程6,linux – Bash:杀死子进程中的所有进程
  10. PL/SQL 之 sql语句的编写
  11. SpringCloud--Eureka 注册中心原理及其搭建
  12. Atitit enhance dev effect提升开发效率的十大原理与方法v3 u66.docx Atitit enhance dev effect提升开发效率的十大原理与方法v2 u66.do
  13. ZXing拍码后区分扫描到的是一维码、二维码、其他码,android音视频面试
  14. python vecm_用Eviews处理有关VARVECM模型的几个问题
  15. 计算机导论的答案,计算机导论答案
  16. Android动态listview,Android列表组件ListView使用详解之动态加载或修改列表数据
  17. web 服务端与客户端交互
  18. dSYM文件解析与分析
  19. pycharm设置字体样式_Pycharm IDE设置系列教程(三):配置颜色和字体
  20. n平方的求和公式_n的二次方怎么求和?

热门文章

  1. 如何使用 GRUB 2 直接从硬盘运行 ISO 文件
  2. 安卓版App开发心得
  3. 在fmri研究中,cca的应用历史
  4. Golang最佳Web框架对比
  5. 快速学习javascript 整体架构方法
  6. 模型算法_详解SVM模型之SMO算法
  7. 以下属于4nf的分解为_数据库原理·模拟试卷及答案(1)
  8. python的基础_毫无基础的人如何入门 Python ?
  9. php测试宽带速度慢,性能测试问题排查一例——网络带宽瓶颈
  10. mysql技术blog_Mysql技术 - 包子博客 _ 关注互联网前端、开发、SEO、移动互联网应用技术...