ARM寻址方式

寻址方式指的是确定操作数位置的方式。

寻址方式:
立即数寻址
直接寻址(绝对寻址),ARM不支持这种寻址方式,但所有CISC处理器都支持
寄存器间接寻址

3种寻址方式总结如下:
助记符 RTL格式 描述

ADD	r0,r1,#Q	[r0]<-[r1] + Q		立即数寻址:把整数Q与寄存器r1的内容相加
LDR	r0,Mem	[r0]<-[Mem]  		绝对寻址:存储单元内容加到寄存器r0中
LDR	r0,[r1]     	[r0]<-[[r1]]		间接寻址:把r1所指存储单元的值加载到r0中

在这里插入图片描述

立即数寻址

在介绍ARM如何实现立即数寻址之前,先来看一个使用立即数寻址的实例。高级语言
常用立即数寻址来指定一个常量而不是变量,如:
IF I > 25
THEN J = K + 12
常量12和25由立即数寻址指定。

假设I在r0中,J在r1中,K在r2中,可表示为:CMP	r0,#25		; 把I与25比较BLE	Exit		; 如果 I <= 25,则退出ADD	r1,r2,#12	; 否则K+12Exit							;
使用条件执行表示:CMP	r0,#25		; I与25比较ADDGT	r1,r2,#12	; 如果I > 25,则J = K + 12

ARM的立即数实现方法

ARM在指令中提供了12位的立即数字段,但不支持值在0~4095之间的12位无符号立即数或
值在-2048~2047之间的12位有符号立即数。实际上ARM提供的是可按2的幂缩放的8位立即
数。
下图,给出了ARM立即数的编码结构,当操作码的第25位为0时,ARM将进行一次移位操
作,当第25位为1时,操作数2字段将编码12位立即数,它被分成两部分:8位立即数和4位
对齐码。
在这里插入图片描述
立即数字段中最高4位知道了立即数在32位字中的对齐方式。
如果8位立即数为N,4位对齐码为 n(范围在0~15之间),则立即数的值为N x 22n,因
此ARM提供了一个可按2的幂缩放的8位立即数,这与浮点数的表示和存储方式相似。

下图描述了一个ARM立即数缩放,该图说明了对齐码是如何在32位框架移动立即数的。为
了得到立即数循环右移的位数,必须将对齐码的数字翻倍。
在这里插入图片描述

尽管不能直接指定32位立即数,但ARM缩放结构可以表示常量FF00000016,即用8位FF16
左移24位(即右移8位)来表示。

取反传送指令MVN r0,r1,#literal,能够指定一个不必移位且范围在0xFFFFFF00到
0xFFFFFFFF的常量。程序员不用担心如何产生移位常量,这是汇编器的工作。立即数的缩
放不是伪操作。

如,指令MOV r1,#0x0000FF00的二进制代码为E3A01CFF16:
MOV r0,#0xFF
MOV r1,#0x0000FF00
MOV r2,#0xFF000000

以指令MOV r1,#0xFF00为例,立即数编码为CFF16(1100111111112),对齐码为C16或1210。
实际移位位数是这个数的2倍,即2410,通过循环右移来实现。24次循环右移操作等于8次
循环左移操作,即将FF16移位为FF0016,最后来看0xFF000000,将十六进制数左移6次,
相当于将二进制左移24次,不过这里使用循环右移,等价于循环右移8次。要保存的缩放
常数(即对齐码)是移位次数的一半,即4。上图中第6行指令的常量编码为4FF。

寄存器的间接寻址

操作数的地址保存在寄存器中,这种寻址方式叫作寄存器间接寻址,也叫索引寻址或基址
寻址。ARM的立即数偏移量为12位。它确实是12位立即数,不是8位可缩放的值。

什么时候是真正的12位

ARM处理器指定12位常量作为立即操作数(如ADD r0,r1,#123)。常量为8位数并通过4位
对齐码进行放大。

然而,当ARM处理器指定某个立即数偏移量作为索引地址的一部分时,它就是真正的12位
数,如LDR r0,[r1,#123]。

寄存器间接寻址

寄存器间接寻址通过3个读操作来访问一个操作数:
(1)读指令得到指针寄存器
(2)读指针寄存器得到操作数地址
(3)读操作数地址所指的存储器单元得到操作数

寄存器间接寻址可以在运行时修改寄存器的内容,而寄存器中含有指向实际操作数的指针
(地址),因此地址是变量,允许访问如数组、列表、矩阵、向量、表格等数据结构。

下图,通过ARM的加载指令LDR r1,[r0]说明了寄存器间接寻址,指针寄存器r0的值为n,则
指向或引用存储单元n:

在这里插入图片描述
LDR r1,[r0]和ADD r0,r0,#4这两个操作的RTL定义:
[r1] <- [[r0]] ; 读取r0所指存储单元的值,[[r0]]就是r0所指存储单元的值
[r0] <- [r0] + 4 ; 指针递增指向下一个存储单元

考虑下面的例子,表格中的7个项分别代表一个星期的每一天。D1代表星期一,D2代表星
期二,等等。如果Di是第i天,则Di+1就表示下一天,从一天移到下一天,只需将索引i加1,
这就是需要变址的原因:

			ADR	r0,Week		; r0指向数组WeekADD	r0,r0,r1, LSL #2		; r0现在指向r1所含那一天LDR	r2,[r0]			; 读取这一天的数据到r2Week	DCD				; 第1天的数据DCD				; 第2天的数据.DCD				; 第7天的数据 

假定天数的索引为0~6,天数的索引必须乘以4,因为这里的数组是字的数组(每个字4个
字节),连续两个元素的地址之差为4。

字符串是一个很好的使用基于指针寻址的例子。假设要找到某个特定字符在字符串中的位
置,可以写出下面代码。这不是ARM代码,因为还没有介绍字节操作。使用下标表明操作
数的大小:

		LDR32	r0,#String		; r0指向StringLoop	LDR8	r1,[r0]			; REPEAT 读取字符ADD32	r0,r0,#1			;	更新字符指针CMP8	r1,#Terminator		; UNTIL	发现终止符(终止符为行结束字符)BNE 	Loop			;	

有些计算机将寄存器间接寻址与指针更新结合在一起,这样指针在被使用之后就可以自动
地指向下一个存储单元。

考虑下面的C代码段:
在这里插入图片描述

程序中数0、21、10是汇编期间有立即数寻址方式指定的常量。转为下面的ARM汇编语言

带偏移量的寄存器间接寻址

操作数有效地址是寄存器的内容加上编码在load/store指令的立即数偏移量,这种寻址方式
也叫基址加位移寻址。

下图,用指令LDR r0,[r1,#4]说明,图中有效地址是指针寄存器r1的内容加上偏移量4的和,
即操作数距离指针所指的地址4个字节:

在这里插入图片描述
下述代码段说明了如何使用偏移量实现数组访问,偏移量是常量,在运行时不能改变:

		Sun	EQU	0	; 一星期中每一天的偏移量Mon	EQU	4			Tue	EQU	8			.Sat	EQU	24		ADR	r0,Week		; r0指向数组WeekLDR	r2,[r0,#Tue]		; 读取星期二的数据到r2LDR	r3,[r0,#Wed]		; 读取星期三的数据到r3ADD	r4,r2,r3		; 星期二的数据与星期三的数据相加STR	r4,[r0,#Mon]		; 把结果存放到星期一Week	DCD			; 第1天的数据(星期天)DCD			; 第2天的数据(星期一)DCD			; 第3天的数据(星期二)DCD			; 第4天的数据(星期三)DCD			; 第5天的数据(星期四)DCD			; 第6天的数据(星期五)DCD			; 第7天的数据(星期六)

ARM允许指定第二个寄存器作为偏移量,这样就可以使用运行时可以修改的动态偏移量,
如下图:
LDR r2,[r0,r1] ; [r2]<-[[r0] + [r1]]把r0加r1所指存储单元的值加载到r2中
LDR r2,[r0,r1,LSL #2] ; [r2]<-[[r0] + 4 x [r1]]将r1乘4
在这里插入图片描述

寄存器r1扩大了4倍。当处理数组时,允许使用一个被缩放的偏移量。如果r0指向数组X且
r1包括索引i,则元素i的地址为X+4i。这样就可以使用指令LDR r2,[r0,r1,LSL #2]访问该元素。

可以通过向基址寄存器增加立即数偏移量或寄存器偏移量来扩展寄存器间接寻址方式。在
ARM术语中,基址寄存器加偏移量的寻址方式叫作前索引,因为是在访问操作数之前把偏
移量加到指针上。指令LDR r0,[r1,#8]指定了前索引寻址方式,操作数的有效地址由[r1]+8给
出。这里,前索引表示偏移量#8在load操作的读阶段访问寄存器之前就被加到基址寄存器
r1上。

前索引寻址方式可以来访问数组X的元素i,如:
ADR r0,X ; 寄存器r0指向数组X
LDR r1,[r0,i] ; 读出元素i

ARM的自动前索引寻址方式

通过将偏移量加到基址寄存器(指针寄存器)上ARM实现了两种自动索引方式。这两种方
式的差别在于基址寄存器递增的时机——要么在访问寄存器之前,要么在之后。

ARM的自动前索引寻址方式是在有效地址后面添加后缀!来表示。如:
LDR r0,[r1,#8]! ; 将寄存器r1+8所指存储单元中的字加载到r0中
; 然后将r1加8以更新指针

RTL定义如下:
[r0] <- [[r1] + 8] 访问地址为基址寄存器r1+8的存储单元
[r1] <- [r1] + 8 加上偏移量更新指针(基址寄存器)

考虑下面两个数组相加的例子:

Len	BQU	8		; 数组长度为8个字ADR	r0,A-4		; 寄存器r0指向数组AADR	r1,B-4		; 寄存器r1指向数组BADR	r2,C-4		; 寄存器r2指向数组CMOV	r5,#Len		; 寄存器r5用作循环计数器
Loop	LDR	r3,[r0,#4]!	; 取出A的元素LDR	r4,[r1,#4]!	; 取出B的元素ADD	r3,r3,r4		; 两元素相加STR	r3,[r2,#4]!	; 和保存到C中SUBS	r5,r5,#1		; 测试循环是否结束BNE	Loop		; 重复直到全部完成

ARM自动后索引寻址方式

自动后索引寻址方式首先访问基址寄存器所指的存储单元中的操作数,然后将基址寄存器
递增。如:
LDR r0,[r1],#8 ; 将r1所指的字加载到r0中,然后完成后索引,即r1加8

后索引把偏移量放在方括号的外面(如[r1],#8),RTL定义为:
[r0] <- [[r1]] 访问基址寄存器r1所指存储单元
[r1] <- [r1] + 8 加上偏移量更新指针(基址寄存器)

在这里插入图片描述
在这里插入图片描述

程序计数器相对寻址

寄存器r15是一个程序计数器,把r15用作访问操作数的指针寄存器,这种寻址方式叫作程
序计数器(PC)相对寻址。操作数地址由其与当前代码的相对位置确定。这意味着可以将
代码及与之相关的数据移动到存储器中的不同地方,而无需重新计算操作数地址。

假设执行指令LDR r0,[r15,#100],操作数地址距离寄存器r15的内容的相对偏移为100字
节(25个字),因此,操作数位于当前位置偏移100字节处。

ARM的load与store指令编码

在这里插入图片描述
访存操作有一条条件执行字段,即操作码的第28~31位,它们可以像其他ARM指令一样条
件执行:

			; if(a==b)	then	x = p else	x = qCMP	r1,r2	; if(a==b)LDREQ	r3,[r4]	;then x = pLDRNE	r3,[r5]	;else x = q

操作码第20位选择数据传送方向,即指令是load还是store
第25位(#位)决定了偏移量是带可选移位的寄存器内容还是12位常量
第22位选择操作数大小,并确定ARM是传送32位字还是8位字节,当字节被加载到32位寄存器中时,
寄存器的第8~31位被置0。
基址寄存器r基址是存储器指针
U位定义了有效地址的计算机是加上还是减去偏移量
W位决定了当前指令结束时基址寄存器是否会被更新,W=1,则会更新基址寄存器
P位控制偏移量是计算机有效地址之前还是在之后被加到基址寄存器上

因为U位决定了对偏移量进行加法还是减法,ARM能使用以下寻址方式:
LDR r0,[r1,+r2] ; 有效地址是[r1] + [r2]
LDR r0,[r1,-r2] ; 有效地址是[r1] – [r2]

下表总结了ARM基于寄存器的寻址方式:
在这里插入图片描述

考虑二进制字符串01010111001000100100000100000110表示一条ARM指令,把这条指令分
解,得到下表中的编码,得到的指令就是STRPL r4,[r2,-r6,LSL #2]!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/81905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学苑教育杂志学苑教育杂志社学苑教育编辑部2025年第9期目录

专题研究 核心素养下合作学习在初中数学中的应用 郑铁洪; 4-6 教育管理 小学班级管理应用赏识教育的策略研究 芮望; 7-9 课堂教学 小学数学概念教学的实践策略 刘淑萍; 10-12 “减负提质”下小学五年级语文课堂情境教学 王利;梁岩; 13-15 小练笔的美丽转身…

关于类型转换的细节(隐式类型转换的临时变量和理解const权限)

文章目录 前言类型转换的细节1. 类型转换的临时变量细节二&#xff1a;const与指针 前言 关于类型转换的细节&#xff0c;这里小编和大家探讨两个方面&#xff1a; 关于类型转化的临时变量的问题const关键字的权限问题 — 即修改权限。小编或通过一道例题&#xff08;配图&am…

技术对暴力的削弱

信息时代的大政治分析&#xff1a;效率对暴力的颠覆 一、工业时代勒索逻辑的终结 工厂罢工的消亡 1930年代通用汽车罢工依赖工厂的物理集中、高资本投入和流水线脆弱性&#xff0c;通过暴力瘫痪生产实现勒索。 信息时代企业分散化、资产虚拟化&#xff08;如软件公司可携带代码…

深入理解分布式锁——以Redis为例

一、分布式锁简介 1、什么是分布式锁 分布式锁是一种在分布式系统环境下&#xff0c;通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据&#xff0c;从而避免数据的不一致性。 线程锁&#xff1a; 也被称为互斥锁&#xff08…

yolo训练用的数据集的数据结构

Football Players Detection using YOLOV11 可以在roboflow上标注 Sign in to Roboflow 训练数据集只看这个data.yaml 里面是train的image地址和classnames 每个image一一对应一个label 第一个位是分类&#xff0c;0是classnames[0]对应的物体&#xff0c;现在是cuboid &…

Redis 使用及命令操作

文章目录 一、基本命令二、redis 设置键的生存时间或过期时间三、SortSet 排序集合类型操作四、查看中文五、密码设置和查看密码的方法六、关于 Redis 的 database 相关基础七、查看内存占用 一、基本命令 # 查看版本 redis-cli --version 结果&#xff1a;redis-cli 8.0.0red…

Java大师成长计划之第13天:Java中的响应式编程

&#x1f4e2; 友情提示&#xff1a; 本文由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;平台gpt-4o-mini模型辅助创作完成&#xff0c;旨在提供灵感参考与技术分享&#xff0c;文中关键数据、代码与结论建议通过官方渠道验证。 随着现代应用程序的复杂性增加&…

华为私有协议Hybrid

实验top图 理论环节 1. 基本概念 Hybrid接口&#xff1a; 支持同时处理多个VLAN流量&#xff0c;且能针对不同VLAN配置是否携带标签&#xff08;Tagged/Untagged&#xff09;。 核心特性&#xff1a; 灵活控制数据帧的标签处理方式&#xff0c;适用于复杂网络场景。 2. 工作…

K8s 常用命令、对象名称缩写汇总

K8s 常用命令、对象名称缩写汇总 前言 在之前的文章中已经陆续介绍过 Kubernetes 的部分命令&#xff0c;本文将专题介绍 Kubernetes 的常用命令&#xff0c;处理日常工作基本够用了。 集群相关 1、查看集群信息 kubectl cluster-info # 输出信息Kubernetes master is run…

【HDLBits刷题】Verilog Language——1.Basics

目录 一、题目与题解 1.Simple wire&#xff08;简单导线&#xff09; 2.Four wires&#xff08;4线&#xff09; 3.Inverter&#xff08;逆变器&#xff08;非门&#xff09;&#xff09; 4.AND gate &#xff08;与门&#xff09; 5. NOR gate &#xff08;或非门&am…

C语言|递归求n!

C语言| 函数的递归调用 【递归求n!】 0!1; 1!1 n! n*(n-1)*(n-2)*(n-3)*...*3*2*1; 【分析过程】 定义一个求n&#xff01;的函数&#xff0c;主函数直接调用 [ Factorial()函数 ] 1 用if语句去实现&#xff0c;把求n!的情况列举出来 2 if条件有3个&#xff0c;n<0; n0||n…

Android第四次面试总结之Java基础篇(补充)

一、设计原则高频面试题&#xff08;附大厂真题解析&#xff09; 1. 单一职责原则&#xff08;SRP&#xff09;在 Android 开发中的应用&#xff08;字节跳动真题&#xff09; 真题&#xff1a;“你在项目中如何体现单一职责原则&#xff1f;举例说明。”考点&#xff1a;结合…

OpenHarmony GPIO应用开发-LED

学习于&#xff1a; https://docs.openharmony.cn/pages/v5.0/zh-cn/device-dev/driver/driver-platform-gpio-develop.md https://docs.openharmony.cn/pages/v5.0/zh-cn/device-dev/driver/driver-platform-gpio-des.md 通过OpenHarmony官方文档指导可获知&#xff1a;芯片厂…

XILINX原语之——xpm_fifo_async(异步FIFO灵活设置位宽、深度)

目录 一、"fwft"模式&#xff08;First-Word-Fall-Through read mode&#xff09; 1、写FIFO 2、读FIFO 二、"std"模式&#xff08;standard read mode&#xff09; 1、写FIFO 2、读FIFO 调用方式和xpm_fifo_sync基本一致&#xff1a; XILINX原语之…

系统学习算法:动态规划(斐波那契+路径问题)

题目一&#xff1a; 思路&#xff1a; 作为动态规划的第一道题&#xff0c;这个题很有代表性且很简单&#xff0c;适合入门 先理解题意&#xff0c;很简单&#xff0c;就是斐波那契数列的加强版&#xff0c;从前两个数变为前三个数 算法原理&#xff1a; 这五步可以说是所有…

《让内容“活”起来:Flutter社交应用瀑布流布局的破界实践》

用户动态的展示方式如同舞台的布景&#xff0c;直接影响着观众——用户的体验。而瀑布流布局&#xff0c;以其独特的美感和高效的信息展示能力&#xff0c;成为众多社交应用的心头好。当我们滑动着Instagram、Pinterest&#xff0c;或是国内热门的小红书&#xff0c;那种内容如…

微机控制技术复习【一】

填空题&#xff1a; 简答题&#xff1a; 1、什么是计算机控制系统?其典型形式有哪些? 2、给出 DDC &#xff08;直接数字控制&#xff09;控制系统结构框图&#xff0c;并说明各组成部分的作用&#xff1f; 3、采样周期选择的理论依据是什么?工程应用中应如何选择?选择采样…

前端学习基础—VScode环境配置及html基础知识

作为初学者&#xff0c;一个好的开发环境能极大地提高理解与学习的效率&#xff0c;本文分享我的VScode环境配置方法&#xff0c;涵盖插件、主题、快捷键等&#xff0c;希望能助你快速搭建舒适边界的前端学习环境。 一、VSCode环境配置 首先找到vscode插件商店&#xff0c;在这…

【一】 基本概念与应用领域【830数字图像处理】

考纲 文章目录 1 概念2005甄题【名词解释】2008、2012甄题【名词解释】可考题【简答题】可考题【简答题】 2 应用领域【了解】2.1 伽马射线成像【核医学影像】☆2.2 X射线成像2.3 紫外波段成像2.4 可见光和红外波段成像2.5 微波波段成像2.6 无线电波段成像2.7 电子显微镜成像2…

QuecPython错误码汇总

QuecPython中定义的各种错误代码常量 错误码常量错误码释义QUEC_PY_FAIL-1Generic failure codesQUEC_PY_OK0Quec_py value indicating success (no error)QUEC_PY_EPERM1Operation not permittedQUEC_PY_ENOENT2No such file or directoryQUEC_PY_ESRCH3No such processQUEC_…