前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >嵌入式:Load/Store之单寄存器的存取指令

嵌入式:Load/Store之单寄存器的存取指令

作者头像
timerring
发布于 2022-12-22 00:35:00
发布于 2022-12-22 00:35:00
82600
代码可运行
举报
文章被收录于专栏:TechBlogTechBlog
运行总次数:0
代码可运行

文章目录

ARM处理器是Load/Store型的,即它对数据的操作是通过将数据从存储器加载到片内寄存器中进行处理,处理完成后的结果经过寄存器存回到存储器中,以加快对片外存储器进行数据处理的速度。

ARM的数据存取指令Load/Store是唯一用于寄存器和存储器之间进行数据传送的指令。

在ARM系统中I/O操作是通过存储器映射进行寻址的,对I/O设备的操作可以和对存储器的操作一样,因此,也是使用Load/Store指令完成。

Load/Store指令分类

ARM指令集中有三种基本的数据存取指令:

  • 单寄存器的存取指令(LDR,STR):提供寄存器和存储器之间最灵活的单数据项传送方式,传送的数据可以是8位字节、16位半字或32位字。
  • 多寄存器存取指令(LDM,STM):可有效地用于大批数据的传送。一般这些指令用于进程的进入和退出,保存和恢复工作寄存器以及拷贝存储器中一块数据。
  • 单寄存器交换指令(SWP):用于寄存器和存储器中的数据交换。在一个指令中完成存取操作。该指令常用来完成信号量操作,而信号量是一种解决进程同步和互斥问题的机制。
单寄存器的存取指令

单寄存器存取指令是ARM在寄存器和存储器间传送单个字节和字的最灵活方式。根据传送数据的类型不同,单个寄存器存取指令又可以分为以下两类:

  • 单字和无符号字节的数据传送指令
  • 半字和有符号字节的数据传送指令
1、单字和无符号字节的数据传送指令

这一类数据传送指令的编码格式如下:

指令说明

基址寄存器加上或减去一个无符号立即数或者 寄存器偏移量构成存储器访问地址。 当从存储器读取一个无符号字节数据时,需要将它用0扩展到32位,然后放置到目的寄存器中。 当从一个寄存器向存储器写一个字节的数据时,写的是寄存器的低8位。 前变址的寻址模式使用计算出的地址作为存储器地址进行数据存取操作,然后,当要求回写(W=1)(即自动变址方式),将基址寄存器更新为计算出的地址值。 后变址的寻址模式用未修改的基址寄存器来传送数据,然后将基址寄存器更新为计算出的地址,而不管W位如何。

指令汇编格式

前变址格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   LDR|STR {<cond>} {B} Rd, [Rn, <offset>] {!}

​ 其中B表示是按字节传送,缺省时按字传送,offset可能是±12位立即数,或者±Rm{},这里shift包括移位方式和移位位数,移位位数只能是5位立即数,而不能再来自于寄存器Rs。根据有无{!}选择是否回写(自动变址)。 后变址格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   LDR|STR {<cond>} {B} {T} Rd, [Rn]<offset>

​ 其中T标志只能在非用户模式(即特权模式)下使用,作用是选择用户角度的存储器访问。 相对PC的形式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   LDR|STR {<cond>} {B} Rd, LABEL 

举例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LDR  R8,[R10]   ;R8[R10]
LDRNE R1,[R5,#960]!  ;(有条件地)R1[R5+960],R5R5+960
STR  R2,[R9,#consta-struc] ;consta-struc是常量表达式,范围为-4095~4095
STRB R0[R3-R8ASR #2]R0[R3-R8÷4],存储R0的最低有效字节,但R3R8的内容不变
LDR  R1,localdata   ;加载一个字,该字位于标号localdata所在地址。(相对PC形式)
LDR  R0,[R1],R2,LSL #2 ;将地址为R1的内存单元数据读取到R0中,然后R1R1+R2*4
LDRB R0[R2,#3] ;将内存单元(R2+3)中的字节数据读到R0中,R0的高24位被设置为0
LDR  R1[R0-R2LSL #2] ;将R0-R2*4地址处的数据读出,保存到R1中,R0R2的值保持不变。
STR  R0,[R7],#-8   ;R0的内容存到R7中地址对应的内存中,R7R7-8

在编程中,常使用相对PC的形式将R0中的一个字存到外设UART,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
       LDR    R1UARTADD
       STR     R0[R1]

​ 或者,使用相对PC形式将外设UART数据读到R0 ,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
       LDR    R1UARTADD
       LDR    R0[R1]

注意:

这里UARTADD标号在附近4KB范围之内。

使用PC作为基址时,得到的传送地址为当前指令地址加8字节;PC不能用作偏移寄存器,也不能用于任何自动变址寻址模式(包括后变址模式)。

把一个字读到PC可以使程序转移到读取的地址,从而实现程序跳转。但应避免将一个字节读取到PC。应尽量避免把PC存储到存储器,因为不同处理器可能会产生不同的结果。

只要不使用自动变址,Rd=Rn是可以的,但在一般情况下,Rd、Rn和Rm应是不同的。

2、半字和有符号字节的数据传送指令

有符号的字节或半字的传送用“符号位”扩展到32位。无符号半字的传送用0扩展到32位。这类数据传送的二进制编码如下:

立即数偏移量只能8位之内。 寄存器偏移量不可移位得到。 S、H用于定义所传送的数据类型。

S

H

数据类型

1

0

有符号字节

0

1

无符号半字

1

1

有符号半字

指令汇编格式

这一类数据传送指令的汇编格式如下:

前变址格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     LDR|STR{ <cond>} H|SH|SB  Rd,  [Rn, <offest>]{!}

后变址格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     LDR|STR {<cond>} H|SH|SB  Rd,  [Rn]<offest> 

式中是#±<8位立即数>或#±Rm;H|SH|SB选择传送数据类型;其它部分的汇编器格式与传送字和无符号字节相同。所有半字传送应使用半字对齐的地址。

举例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LDREQSH  R11,[R6];(有条件地) R11[R6],加载16位半字,有符号扩展到32LDRH R1,[R0,#20]!R1[R0+20],加载16位半字,0扩展到32STRH  R4,[R3R2] ;R4[R3+R2],存储最低的有效半字到R3+R2
LDRSB R0const ;加载位于标号const地址的字节,有符号扩展
LDRH  R6[R2],#2 ;R2地址上的半字数据读出到R6,高16位用0扩展,R2=R2+2
LDRSH  R1,[R9];R9地址上的半字数据读取到R1中,高16位用符号位扩展
STRNEH  R0[R2,#960] (有条件地)将R0的内容送到(R2+960)的内存中,R2=R2+960

参考文献:

孟祥莲.嵌入式系统原理及应用教程(第2版)[M].北京:清华大学出版社,2017.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
嵌入式:ARM多寄存器存取指令详解
多寄存器传送指令可以用一条指令将16个可见寄存器(R0~R15)的任意子集合(或全部)存储到存储器或从存储器中读取数据到该寄存器集合中。如:可将寄存器列表保存到堆栈,也可将寄存器列表从堆栈中恢复。 这种指令有两个特殊用法: (1)允许操作系统加载或存储用户模式寄存器来保护或恢复用户处理状态。 (2)作为异常处理返回的一部分,完成从SPSR中恢复CPSR。 这种指令与单寄存器存取指令相比,多寄存器数据存取可用的寻址模式更加有限。
timerring
2022/12/23
6290
嵌入式:ARM多寄存器存取指令详解
LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA指令详解
简介: ARM指令中多数据传输共有两种: LDM:(load  much)多数据加载,将地址上的值加载到寄存器上 STM:(store much)多数据存储,将寄存器的值存到地址上 主要用途:现场保护
诺谦
2018/01/03
3.4K0
汇编语言之ARM32汇编
以上两种编译环境,使用的指令集都是一致的, 只是语法格式有不同,也就是宏指令,伪指令,伪操作不一样
乱码三千
2021/08/24
3.3K0
汇编语言之ARM32汇编
【嵌入式开发】 ARM 关闭 MMU ( 存储体系 | I/D-Cache | MMU | CP15 寄存器 | C1 控制寄存器 | C7 寄存器 | 关闭 MMU )
ARM 存储 体系 简介 : ARM 处理器分为三个等级, 处理器寄存器 -> TCM 存储器 -> 辅助存储器, 由上到下, 处理速度依次变慢, 但是存储空间依次增加 ;
韩曙亮
2023/03/27
2.6K0
【嵌入式开发】 ARM 关闭 MMU ( 存储体系 | I/D-Cache | MMU | CP15 寄存器 | C1 控制寄存器 | C7 寄存器 | 关闭 MMU  )
ARM指令集介绍「建议收藏」
ARM 指令集是针对ARM体系架构设计的指令。在BootLoader引导的第一阶段以及内核的第一阶段都会有一个使用汇编语言编写的文件,在不跑操作系统的裸板中也有一段用来初始化开发板环境的汇编代码。所以无论是开发带操作系统的板子,还是裸板开发,汇编语言都很有必要学习一番,最少要了解一些常用的汇编指令。要想设计出性能超强的系统,ARM的工作原理是必须掌握的。
全栈程序员站长
2022/11/15
2.8K0
ARM指令集介绍「建议收藏」
嵌入式:ARM数据定义伪操作全总结
DCW(或DCWU)伪操作用于分配一片连续的半字存储单元并用伪操作中指定的表达式初始化。其中,表达式可以为程序标号或数值表达式。用DCW分配的字存储单元是半字对齐的,而用DCWU分配的字存储单元并不严格按照半字对齐。
timerring
2022/12/30
4710
ARM指令集
ARM指令的基本格式为: <Opcode> {<Cond>} {S} <Rd>, <Rn> { , <Opcode2> } 其中,<>内的项是必需的,{}内的项是可选的。 1)Opcode项 Opcode是指令助记符,即操作码,说明指令需要执行的操作,在指令中是必需的。 2)Cond项(command) Cond项表明了指令的执行的条件,每一条ARM指令都可以在规定的条件下执行,每条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。 条件码共有16种,每种条件码用2个字符表示,这两个字符可以添加至指令助记符的后面,与指令同时使用。 当指令的执行条件满足时,指令才被执行,否则指令被忽略。如果在指令后不写条件码,则使用默认条件AL(无条件执行)。 指令的条件码 条 件 码 助记符后缀 标 志 含 义 0000 EQ Z置位 相等equal 0001 NE Z清零 不相等not equal 0010 CS C置位 无符号数大于或等于Carry Set 0011 CC C清零 无符号数小于 0100 MI N置位 负数minus 0101 PL N清零 正数或零plus 0110 VS V置位 溢出 0111 VC V清零 没有溢出 1000 HI C置位Z清零 无符号数大于high 1001 LS Z置位C清零 无符号数小于或等于less 1010 GE N等于V 带符号数大于或等于 1011 LT N不等于V 带符号数小于least 1100 GT Z清零且(N等于V) 带符号数大于great 1101 LE Z清零或(N不等于V) 带符号数小于或等于 1110 AL 忽略 无条件执行all 1111 条件码应用举例: 例:比较两个值大小,并进行相应加1处理,C语言代码为: if ( a > b ) a++; else b++; 对应的ARM指令如下(其中R0中保存a 的值,R1中保存b的值): CMP R0, R1 ; R0与R1比较,做R0-R1的操作 ADDHI R0, R0, #1 ;若R0 > R1, 则R0 = R0 + 1 ADDLS R1, R1, #1 ; 若R0 <= R1, 则R1 = R1 + 1 CMP比较指令,用于把一个寄存器的内容和另一个寄存器的内容或一个立即数进行比较,同时更新CPSR中条件标志位的值。指令将第一操作数减去第二操作数,但不存储结果,只更改条件标志位。 CMP R1, R0 ;做R1-R0的操作。 CMP R1,#10 ;做R1-10的操作。 3)S项(sign) S项是条件码设置项,它决定本次指令执行的结果是否影响至CPSR寄存器的相应状态位的值。该项是可选的,使用时影响CPSR,否则不影响CPSR。 4)
全栈程序员站长
2022/07/05
8160
嵌入式:ARM间接寻址、变址寻址与多寄存器寻址
寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。例如以下指令:
timerring
2022/12/19
1.6K0
嵌入式:ARM间接寻址、变址寻址与多寄存器寻址
ARM汇编简单学习
ARM汇编语言是针对ARM架构设计的低级编程语言,用于直接操作硬件和编写高效的系统级程序。
cultureSun
2024/03/28
1910
爱了爱了,这篇寄存器讲的有点意思
下面我们就来介绍一下关于寄存器的相关内容。我们知道,寄存器是 CPU 内部的构造,它主要用于信息的存储。除此之外,CPU 内部还有运算器,负责处理数据;控制器控制其他组件;外部总线连接 CPU 和各种部件,进行数据传输;内部总线负责 CPU 内部各种组件的数据处理。
C语言与CPP编程
2020/12/10
5.5K0
爱了爱了,这篇寄存器讲的有点意思
【嵌入式开发】ARM 关闭中断 ( CPRS 中断控制位 | 中断使能寄存器 | 中断屏蔽寄存器 | 关闭中断 | 汇编代码编写 )
CPRS 设置 值 分析 : 该寄存器需要考虑两个方面, ① 设置处理器的 SVC 工作模式, ② 关闭中断 ;
韩曙亮
2023/03/27
9.5K0
【嵌入式开发】ARM 关闭中断  ( CPRS 中断控制位 | 中断使能寄存器 | 中断屏蔽寄存器 | 关闭中断 | 汇编代码编写 )
ARM汇编语言指令集汇总
ARM汇编语言指令集汇总 跳转指令 存储器和寄存器交互数据指令(内存访问) 数据传送指令 数据算术运算指令 数据逻辑运算指令 比较指令 组合和分离指令 并行指令 测试指令 ThumbEE指令 协处理器指令 伪指令 无线 MMX 技术伪指令 其他指令 寄存器寻址方式 跳转指令 指令 简介 B 无条件跳转 BL 带链接的无条件跳转 BX 带状态跳转,更改指令集 BLX 带链接和状态切换的无条件跳转,更改指令集 BXJ 跳转,更改为 Jazelle TBB , TBH 表跳转字节、半字 存储器和寄存器交互数据指
李玺
2021/11/22
1.4K0
arm(2)| 汇编指令和伪指令
指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以由CPU读取执行。伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过程,经过编译后伪指令最终不会生成机器码。所以指令和伪指令最大区别就是编译完之后会不会生成机器码。
飞哥
2020/07/10
2.8K0
arm(2)| 汇编指令和伪指令
嵌入式:ARM协处理器指令总结
ARM支持16个协处理器,用于各种协处理器操作,最常使用的协处理器是用于控制片上功能的系统协处理器,例如控制ARM720上的高速缓存和存储器管理单元等,也开发了浮点ARM协处理器,还可以开发专用的协处理器。
timerring
2022/12/27
7230
嵌入式:ARM协处理器指令总结
【学员笔记分享】二进制逆向学习笔记:汇编之通用寄存器
https://blog.csdn.net/cqkxboy168/article/details/8994479
Ms08067安全实验室
2020/07/14
1.1K0
arm汇编指令详解带实例_汇编buf指令
两个 S 用于不同的指令,名称相同,但是在不同的指令结合却有不同的作用
全栈程序员站长
2022/11/04
1.5K0
《微机原理与接口技术》期末复习笔记「建议收藏」
​ ■ 寻址:确定设备的地址,区分不同的设备; ​ ■ 缓冲:适配外设与CPU的工作速度; ​ ■ 转换:适配外设与CPU的信息格式、类型、幅度; ​ ■ 时序:外设与CPU的工作时序。
全栈程序员站长
2022/11/10
3.8K0
《微机原理与接口技术》期末复习笔记「建议收藏」
OpenHarmony 内核源码分析 (编码方式篇) | 机器指令是如何编码的?
本篇说清楚 ARM指令是如何被编码的,机器指令由哪些部分构成,指令有哪些类型,每种类型的语法又是怎样的 ?
小帅聊鸿蒙
2025/04/03
1060
OpenHarmony 内核源码分析 (编码方式篇) | 机器指令是如何编码的?
寄存器与七种寻址方式
BH(8位) BL(8位) BX(16位) (BX又称基址寄存器,唯一作为存储器指针使用寄存器)
全栈程序员站长
2022/07/12
3K0
安卓逆向:这是一篇逆向基础ARM32指令集的总结
这是一篇关于ARM32指令集的总结文章,后续会不断输出一系列逆向分析破解相关的文章。
小道安全
2021/01/18
2.2K0
安卓逆向:这是一篇逆向基础ARM32指令集的总结
推荐阅读
相关推荐
嵌入式:ARM多寄存器存取指令详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验