00. 目录

文章目录

  • 00. 目录
  • 01. Load/Store指令概述
  • 02. 单寄存器的Load/Store指令
    • 2.1 LDR 指令
    • 2.2 STR 指令
    • 2.3 LDRB 指令
    • 2.4 STRB 指令
    • 2.5 LDRH 指令
    • 2.6 STRH 指令
  • 03. 多寄存器的Load/Store内存访问指令
    • 3.1 LDM 指令
    • 3.2 STM 指令
    • 3.3 数据传送指令应用
  • 04. 单数据交换指令
    • 4.1 SWP 字交换指令
    • 4.2 SWPB 字节交换指令
    • 4.3 交换指令 SWP 应用
  • 05. 附录

01. Load/Store指令概述

Load/Store 内存访问指令在 ARM 寄存器和存储器之间传送数据。ARM 指令中有 3 种基本的数据传送指令。

(1)单寄存器 Load/Store 指令(Single Register),这些指令在 ARM 寄存器和存储器之间提供更灵活的单数据项传送方式。数据项可以是字节、16 位半字或 32 位字。

(2)多寄存器 Load/Store 内存访问指令。这些指令的灵活性比单寄存器传送指令差,但可以使大量的数据更有效地传送。它们用于进程的进入和退出、保存和恢复工作寄存器及复制存储器中的一块数据。

(3)单寄存器交换指令(Single Register Swap)。这些指令允许寄存器和存储器中的数值进行交换,在一条指令中有效地完成 Load/Store 操作。它们在用户级编程中很少用到。它的主要用途是在多处理器系统中实现信号量(Semaphores)的操作,以保证不会同时访问公用的数据结构。

(4)单寄存器的 Load/Store 指令,这种指令用于把单一的数据传入或者传出一个寄存器。支持的数据类型有字节(8 位)、半字(16 位)和字(32 位)。

02. 单寄存器的Load/Store指令

如表 3-8 所示列出了所有单寄存器的 Load/Store 指令。

2.1 LDR 指令

LDR 指令用于从内存中将一个 32 位的字读取到目标寄存器。

(1) 指令的语法格式

LDR{<cond>} <Rd>,<addr_mode>

(2) 应用示例

LDR R1,[R0,#0x12] ;将 R0+12 地址处的数据读出,保存到 R1 中(R0 的值不变)LDR R1,[R0]  ;将 R0 地址处的数据读出,保存到 R1 中(零偏移)LDR R1,[R0,R2] ;将 R0+R2 地址的数据读出,保存到 R1 中(R0 的值不变)LDR R1,[R0,R2,LSL #2]  ;将 R0+R2×4 地址处的数据读出,保存到 R1 中(R0、R2 的值不变)LDR Rd,label  ;label 为程序标号,label 必须是当前指令的-4~4KB 范围内LDR Rd,[Rn],#0x04 ;Rn 的值用作传输数据的存储地址。在数据传送后,将偏移量 0x04 与 Rn 相加,#结果写回到 Rn 中。Rn 不允许是 R15

2.2 STR 指令

STR 指令用于将一个 32 位的字数据写入到指令中指定的内存单元。

(1) 指令的语法格式

STR{<cond>} <Rd>,<addr_mode>

(2) 应用示例

LDR/STR 指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等,若使用 LDR 指令加载数据到 PC 寄存器,则实现程序跳转功能,这样也就实现了程序散转。

① 变量访问。

NumCount .equ 0x40003000  ;定义变量 NumCount
LDR R0,=NumCount  ;使用 LDR 伪指令装载 NumCount 的地址到 R0
LDR R1,[R0]  ;取出变量值
ADD R1,R1,#1  ;NumCount=NumCount+1
STR R1,[R0]  ;保存变量

② GPIO 设置。

GPIO—BASE .equ 0xe0028000 ;定义 GPIO 寄存器的基地址
…
LDR R0,=GPIO—BASE
LDR R1,=0x00ffff00  ;将设置值放入寄存器
STR R1,[R0,#0x0C] ;IODIR=0x00ffff00,IOSET 的地址为 0xE0028004

③ 程序散转。

…
MOV R2,R2,LSL #2  ;功能号乘以 4,以便查表
LDR PC,[PC,R2] ;查表取得对应功能子程序地址并跳转
NOP
FUN—TAB .word FUN—SUB0
.word FUN—SUB1
.word FUN—SUB2
…

2.3 LDRB 指令

LDRB 指令根据 addr_mode 所确定的地址模式将一个 8 位字节读取到指令中的目标寄存器 Rd。

指令的语法格式

LDR{<cond>}B <Rd>, <addr_mode>

2.4 STRB 指令

STRB 指令从寄存器中取出指定的 8 位字节放入寄存器的低 8 位,并将寄存器的高位补 0。

指令的语法格式

STR{<cond>}B <Rd>,<addr_mode>

2.5 LDRH 指令

LDRH 指令用于从内存中将一个 16 位的半字读取到目标寄存器。如果指令的内存地址不是半字节对齐的,指令的执行结果不可预知。

指令的语法格式

LDR{<cond>}H <Rd>,<addr_mode>

2.6 STRH 指令

STRH 指令从寄存器中取出指定的 16 位半字放入寄存器的低 16 位,并将寄存器的高位补 0。

指令的语法格式

STR{<cond>}H <Rd>,<addr_mode>

03. 多寄存器的Load/Store内存访问指令

多寄存器的 Load/Store 内存访问指令又称批量加载/存储指令,它可以实现在一组寄存器和一块连续的内存单元之间传送数据。LDM 用于加载多个寄存器,STM 用于存储多个寄存器。多寄存器的 Load/Store 内存访问指令允许一条指令传送 16 个寄存器的任何子集或所有寄存器。多寄存器的 Load/Store 内存访问指令主要用于现场保护、数据复制和参数传递等。

如下表所示列出了多寄存器的 Load/Store 内存访问指令。

3.1 LDM 指令

LDM 指令将数据从连续的内存单元中读取到指令中指定的寄存器列表中的各寄存器中。当 PC 包含在 LDM 指令的寄存器列表中时,指令从内存中读取的字数据将被作为目标地址值,指令执行后程序将从目标地址处开始执行,从而实现了指令的跳转。

指令的语法格式

LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>

寄存器 R0~R15 分别对应于指令编码中 bit[0]~bit[15]位。如果 Ri 存在于寄存器列表中,则相应的位等于 1,否则为 0。LDM 指令将数据从连续的内存单元中读取到指令中指定的寄存器列表中的各寄存器中。

指令的语法格式

LDM{<cond>}<addressing_mode><Rn>,<registers_without_pc>

3.2 STM 指令

STM 指令将指令中寄存器列表中的各寄存器数值写入到连续的内存单元中。主要用于块数据的写入、数据栈操作及进入子程序时保存相关寄存器的操作。

指令的语法格式

STM{<cond>}<addressing_mode> <Rn>{!}, <registers>

STM 指令将指令中寄存器列表中的各寄存器数值写入到连续的内存单元中。主要用于块数据的写入、数据栈操作及进入子程序时保存相关寄存器等操作。

指令的语法格式

STM{<cond>}<addressing_mode> <Rn>, <registers >ˆ

3.3 数据传送指令应用

LDM/STM 批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM 为加载多个寄存器,STM 为存储多个寄存器。允许一条指令传送 16 个寄存器的任何子集或所有寄存器。

指令格式如下

LDM{cond}<模式> Rn{!},regist{ˆ}
STM{cond}<模式> Rn{!},regist{ˆ}

LDM/STM 的主要用途有现场保护、数据复制和参数传递等。其模式有 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},寄存器排列由小到大排列;“ˆ”后缀不允许在用户模式下使用,只能在系统模式下使用。若在 LDM 指令用寄存器列表中包含有 PC 时使用,那么除了正常的多寄存器传送外,将 SPSR 复制到 CPSR 中,这可用于异常处理返回;使用“ˆ”后缀进行数据传送且寄存器列表不包含 PC 时,加载/存储的是用户模式寄存器,而不是当前模式寄存器。

LDMIA R0!,{R3~R9} ;加载 R0 指向的地址上的多字数据,保存到 R3~R9 中,R0 值更新
STMIA R1!,{R3~R9} ;将 R3~R9 的数据存储到 R1 指向的地址上,R1 值更新
STMFD SP!,{R0~R7,LR}  ;现场保存,将 R0~R7、LR 入栈
LDMFD SP!,{R0~R7,PC}ˆ  ;恢复现场,异常处理返回

在进行数据复制时,先设置好源数据指针,然后使用块复制寻址指令 LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB 进行读取和存储。而进行堆栈操作时,则要先设置堆栈指针,一般使用 SP,然后使用堆栈寻址指令 STMFD/LDMFD、
STMED/LDMED、STMEA/LDMEA 实现堆栈操作。数据是存储在基址寄存器的地址之上还是之下,地址是存储第一个值之前还是之后、增加还是减少,如下表所示。

应用示例一 使用 LDM/STM 进行数据复制

LDR R0,=SrcData  ;设置源数据地址
LDR R1,=DstData  ;设置目标地址
LDMIA R0,{R2~R9} ;加载 8 字数据到寄存器 R2~R9
STMIA R1,{R2~R9} ;存储寄存器 R2~R9 到目标地址

应用示例二 使用 LDM/STM 进行现场寄存器保护,常在子程序或异常处理使用

SENDBYTE:
STMFD SP!,{R0~R7,LR} ;寄存器压栈保护
…
BL DELAY ;调用 DELAY 子程序
…
LDMFD SP!,{R0~R7,PC} ;恢复寄存器,并返回

04. 单数据交换指令

交换指令是 Load/Store 指令的一种特例,它把一个寄存器单元的内容与寄存器内容交换。交换指令是一个原子操作(Atomic Operation),也就是说,在连续的总线操作中读/写一个存储单元,在操作期间阻止其他任何指令对该存储单元的读/写。

交换指令如下表所示。

4.1 SWP 字交换指令

SWP 指令用于将内存中的一个字单元和一个指定寄存器的值相交换。操作过程如下:假设内存单元地址存放在寄存器中,指令将中的数据读取到目的寄存器 Rd 中,同时将另一个寄存器的内容写入到该内存单元中。当和为同一个寄存器时,指令交换该寄存器和内存单元的内容。

指令的语法格式

SWP{<cond>} <Rd>,<Rm>,[<Rn>]

4.2 SWPB 字节交换指令

SWPB 指令用于将内存中的一个字节单元和一个指定寄存器的低 8 位值相交换,操作过程如下:假设内存单元地址存放在寄存器中,指令将中的数据读取到目的寄存器 Rd 中,寄存器 Rd 的高 24 位设为 0,同时将另一个寄存器的低 8 位内容写入到该内存字节单元中。当和为同一个寄存器时,指令交换该寄存器低 8 位内容和内存字节单元的内容。

指令的语法格式

SWP{<cond>}B <Rd>,<Rm>,[<Rn>]

4.3 交换指令 SWP 应用

SWP 指令用于将一个内存单元(该单元地址放在寄存器 Rn 中)的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写到该内存单元中,使用 SWP 可实现信号量操作。

指令的语法格式

SWP{cond}B Rd,Rm,[Rn]

其中,B 为可选后缀,若有 B,则交换字节;否则交换 32 位字。Rd 为目的寄存器,存储从存储器中加载的数据,同时,Rm 中的数据将会被存储到存储器中。若 Rm 与 Rn 相同,则为寄存器与存储器内容进行交换。Rn 为要进行数据交换的存储器地址,Rn 不能与Rd 和 Rm 相同。

SWP 指令举例

SWP R1,R1,[R0] ;将 R1 的内容与 R0 指向的存储单元内容进行交换
SWPB R1,R2,[R0]  ;将 R0 指向的存储单元内容读取一字节数据到 R1 中(高 24 位清零), 并将 R2 的内容
写入到该内存单元中(最低字节有效),使用 SWP 指令可以方便地进行信号量操作
12C_SEM .equ 0x40003000
…
12C_SEM_WAIT:
MOV R0,#0
LDR R0,=12C_SEM
SWP R1,R1,[R0]  ;取出信号量,并将其设为 0
CMP R1,#0  ;判断是否有信号
BEQ 12C_SEM_WAIT ;若没有信号则等待

05. 附录

5.1 ARM Architecture Reference Manual

【ARM】Load Store指令相关推荐

  1. ARM指令详解之Load/Store指令

    Load/Store指令 Load/Store指令用于寄存器和内存间数据的传送. Load 用于把内存中的数据装载到寄存器中. Store用于把寄存器中的数据存入内存. 该集合的指令使用频繁,在指令集 ...

  2. [ARM-assembly]-A64的load/store指令总结

    ★★★个人博客导读首页-点击此处 ★★★ 文章目录 1.Load-Store Single Register 单寄存器读写 2.Load-Store Single Register (unscaled ...

  3. ARM:特殊功能寄存器、Load/Store内存读写指令、栈操作指令

    1.特殊功能寄存器读写指令 msr -->>将普通寄存器中的数据写到特殊寄存器中 mrs -->>将特殊寄存器中的数据写到普通寄存器中 注:特殊寄存器 cpsr 的读写访问只能 ...

  4. ARM开发基础--指令,异常源及处理过程

    本文主要面向初次接触ARM的初学者,主要做基础知识的讲解与科普,希望能对初学者有所帮助. 文章目录 前言 一.什么是指令?指令有哪些? 二.常用指令 1.数据处理指令 2.数据跳转指令 3.Load/ ...

  5. 【ARM】协处理器指令

    00. 目录 文章目录 00. 目录 01. 协处理器指令概述 02. ARM寄存器到协处理器寄存器的数据传送指令MCR 2.1 指令编码格式 2.2 指令的语法格式 2.3 指令举例 2.4 指令的 ...

  6. 【干货来袭】arm程序汇编指令总结,让你更高效的学习!

    现在学嵌入式的人也是越来越多了,那当然arm程序也是必须要学的,在这里有很多人对arm程序汇编指令都或多或少的不了解,可以说不熟悉,今天就以arm程序来看,让你对arm程序汇编指令有更深入的学习. 首 ...

  7. ARM 9 指令系统指令英文全拼

    文章目录 ARM 处理器的寻址方式 寄存器移位寻址 ARM 指令集 条件码 ARM 数据处理类指令 ARM 分支指令 ARM 存储器访问指令 ARM 协处理器指令 ARM 软件中断指令 ARM处理器的 ...

  8. Intel Core Enhanced Core架构/微架构/流水线 (14) - 存储器/内存读写 Memory Load/Store

    Loads 当指令从回写类型的存储器中读取某个地址时,处理器会按照如下的规则从高速缓存或存储器中查找数据(确切的说是匹配地址): 发起核(即执行读存指令的处理器核)的一级数据缓存 其他核的一级数据缓存 ...

  9. 计组高分笔记:【05】中央处理器 「CPU细节 | 取指周期 | 间址周期 | 执行周期 | 中断周期 | 数据通路 | 硬布线控制器 | 微程序控制器 | 指令流水线 | LOAD | STORE」

    文章目录 1. CPU的功能和基本结构 1.1 CPU的组成 1.1.1 运算器的基本组成 1.2.2 控制器的基本组成 1.2.3 CPU的总图 2. 指令执行过程 2.1 指令周期 2.2 指令的 ...

最新文章

  1. sqlite3_exec
  2. python桌面应用html_是否将Python后端与HTML / CSS / JS用户界面集成到桌面应用程序? - javascript...
  3. php获取内存峰值,php内存\获取\使用
  4. ASP.NET MVC 学习之路-5
  5. C#如何直接调用非托管代码
  6. java方法中与参数怎么调用,java中怎么从一个方法中调用另一个方法中的参数?(以及如何提取数字)...
  7. linux下rsync+sersync实现自动备份数据
  8. jfinal 普通java工程_JFinal getModel方法如何在java项目中使用
  9. 如何改变“只收藏不阅读”的习惯
  10. C++学生信息管理系统1.0
  11. 电视视频直播在线播放网站PHP源码V1.2
  12. vue使用wangeditor自定义表情替换QQ表情
  13. 软件选择,iDreamPiano、freepiano、EveryonePiano
  14. 打造万物识别之利器!微信扫一扫植物识别篇技术解析
  15. python爬取链家二手房信息并存储到数据库
  16. 2013-2015南京大学历史学系若干考试题目汇编
  17. 对英文字母按照不区分大小写进行排序
  18. 女超人、女强人……究竟是谁在以“女”设限?
  19. 和导师的微信聊天翻车现场,你一定经历过
  20. Git学习二、GitLab官网,安装自己的一个私有Gitlab代码管理库

热门文章

  1. HDU 4162 Shape Number(最小表示法)
  2. 在Mapnik中显示中文(网上资料整理)
  3. 16个经典面试问题回答规律
  4. 上项线体表位置_实用人体体表解剖:头颈部(高清大图版)
  5. 如何安装php网站,如何安装部署PHP网站
  6. 【SSH异常】InvalidDataAccessApiUsageException异常
  7. Nginx-----相关配置-详细介绍
  8. [转]系统吞吐量(TPS)、用户并发量、性能测试概念和公式---学习
  9. JavaScript原生对象属性和方法详解——String对象
  10. 黑马程序员_集合学习1