【ARM】v8架构programmer guide(4)_ARMv8的寄存器
目录
4.4Endianness(端序或字节序)
4.5 改变execution state
4.5.1 Registers at AArch32
4.5.2 PSTATE at AArch32
4.6 NEON 和浮点数寄存器
4.6.1 AArch64中浮点寄存器的组织结构
4.6.2 标量寄存器大小
4.6.3 向量寄存器大小
4.6.4 NEON在AArch32执行状态
4.4Endianness(端序或字节序)
在计算机体系结构中,有两种基本的内存中字节的视图,即小端序(Little-Endian, LE)和大端序(Big-Endian, BE):
-
大端序(Big-Endian, BE):在大端序的机器上,一个对象(如整数或浮点数)的内存中最高有效字节(Most Significant Byte, MSB)存储在最低的地址上,即最接近于零的地址。这意味着当你查看内存时,首先是最重要的字节。
-
小端序(Little-Endian, LE):在小端序的机器上,对象的最低有效字节(Least Significant Byte, LSB)存储在最低的地址上。这意味着内存中首先出现的是最不重要的字节。
-
字节序(Byte-Ordering):有时也使用“字节序”这个词来代替“端序”(endianness),表达的是相同的概念。
-
影响:字节序的选择会影响多字节数据类型在内存中的存储方式,这在数据传输和处理时尤为重要,尤其是在不同架构的系统之间进行通信时。
-
示例:假设有一个32位的整数0x12345678,在大端序系统中,它在内存中的存储顺序将是:
- 地址0x00: 0x12
- 地址0x01: 0x34
- 地址0x02: 0x56
- 地址0x03: 0x78
而在小端序系统中,存储顺序将是:
- 地址0x00: 0x78
- 地址0x01: 0x56
- 地址0x02: 0x34
- 地址0x03: 0x12
-
系统设计:不同的系统设计选择不同的字节序,这取决于历史原因、特定的系统需求或性能考虑。
-
兼容性:了解系统的字节序对于编写能够在不同架构之间正确交换数据的软件非常重要。
4.5 改变execution state
我们从异常级别的角度描述了在AArch64和AArch32之间切换执行状态。现在我们从寄存器的角度来考虑这种切换:
当从使用AArch32的异常级别进入使用AArch64的异常级别时:
- 在使用AArch32执行的任何较低异常级别上可访问的寄存器的高32位值是未知的。
- 在AArch32执行期间不可访问的寄存器保留着在AArch32执行之前的状态。
- 在异常进入EL3时,如果EL2一直在使用AArch32,则ELR_EL2的高32位值是未知的。
- 与AArch64栈指针(SPs)和异常链接寄存器(ELRs)相关联的异常级别,在AArch32执行期间不可访问,在该异常级别上,保留着它们在AArch32执行之前的状态。这适用于以下寄存器:
- SP_EL0。
- SP_EL1。
- SP_EL2。
- ELR_EL1。
通常,应用程序程序员只为AArch32或AArch64编写应用程序。只有操作系统(OS)必须考虑这两种执行状态以及它们之间的切换。这意味着操作系统需要能够处理两种架构的上下文切换,确保在切换执行状态时,应用程序和系统能够正确地保存和恢复状态。
4.5.1 Registers at AArch32
AArch32与ARMv7在功能上几乎相同,这意味着AArch32必须匹配ARMv7的特权级别。同样,AArch32只处理ARMv7的32位通用寄存器。因此,ARMv8架构及其在AArch32执行状态下提供的视图之间必须存在某种对应关系。
请记住,在ARMv7架构中有十六个32位通用寄存器(R0-R15)供软件使用。其中十五个(R0-R14)可以用于通用数据存储。剩下的一个寄存器,R15,是程序计数器(PC),当核心执行指令时,其值会改变。软件还可以访问当前程序状态寄存器(CPSR),以及之前执行模式中CPSR的保存副本,即保存程序状态寄存器(SPSR)。在触发异常时,CPSR的值会被复制到异常目标模式的SPSR。
访问哪些寄存器以及在何处访问,取决于软件正在执行的处理器模式以及寄存器本身。这称为寄存器银行(banking),下图中的阴影寄存器就是banking的。它们使用物理上不同的存储空间,并且通常只有在进程在特定模式下执行时才能访问。
寄存器bank是一种机制,允许不同模式或异常级别拥有自己的寄存器集,从而在不同上下文之间提供隔离。这种隔离确保了操作系统和应用程序的稳定性和安全性,因为每个模式都可以维护自己的执行状态,而不会影响其他模式的状态。在AArch32执行状态下,这种机制允许软件与ARMv7架构保持兼容性,同时在ARMv8架构上运行。
在ARMv7中,寄存器bank(banking)被用来减少异常处理的延迟。然而,这也意味着在任何给定时间,可能的寄存器中少于一半可以被使用。相比之下,AArch64执行状态拥有31个64位通用寄存器,这些寄存器在所有异常级别上始终可访问。
在AArch64和AArch32之间的执行状态改变意味着AArch64寄存器必须映射到AArch32(ARMv7)寄存器集上。这种映射在下图中展示。
当在AArch32下执行时,AArch64寄存器的高32位是不可访问的。如果处理器在AArch32状态下运行,它使用32位的W寄存器,这些寄存器等同于32位ARMv7寄存器。
AArch32将银行化的寄存器映射到在AArch64状态下原本不可访问的寄存器。这种映射确保了两种执行状态之间的兼容性和过渡,允许操作系统和应用程序根据需要在AArch64和AArch32之间切换,同时保持数据和上下文的一致性。这种设计也简化了从ARMv7到ARMv8的迁移过程,因为它允许现有软件在新的64位架构上运行,尽管可能需要一些调整以利用AArch64的全部功能。
在AArch32中,SPSR(Saved Program Status Register)和ELR_Hyp(Exception Link Register for Hypervisor)是额外的寄存器,只能通过系统指令访问。它们没有映射到AArch64架构的通用寄存器空间中。以下是AArch32和AArch64之间的一些寄存器映射关系:
- SPSR_svc(服务程序状态寄存器)映射到SPSR_EL1。
- SPSR_hyp(虚拟机监视器程序状态寄存器)映射到SPSR_EL2。
- ELR_hyp(虚拟机监视器异常链接寄存器)映射到ELR_EL2。
以下是仅在AArch32执行期间使用的寄存器。然而,由于在AArch64的EL1上执行,尽管在该异常级别上执行AArch64时它们不可访问,但它们仍然保留其状态:
- SPSR_abt(异常服务程序状态寄存器)。
- SPSR_und(未定义服务程序状态寄存器)。
- SPSR_irq(中断服务程序状态寄存器)。
- SPSR_fiq(快速中断服务程序状态寄存器)。
SPSR寄存器仅在AArch64的更高异常级别上执行时用于上下文切换,并且在这些级别上可访问。
再次强调,如果从AArch32的异常级别触发异常到AArch64的异常级别,AArch64的ELR_ELn的高32位将全部为零。这意味着在进行状态转换时,AArch64的异常链接寄存器的高32位不会被AArch32状态中的相应寄存器值所影响,而是被清零,以确保在AArch64环境中以一致的64位状态进行处理。
4.5.2 PSTATE at AArch32
在AArch64中,传统CPSR(Current Program Status Register)的不同组件被呈现为处理器状态(Processor State, PSTATE)字段,这些字段可以独立访问。而在AArch32中,有额外的字段对应于ARMv7 CPSR的位。
4.6 NEON 和浮点数寄存器
ARMv8除了拥有通用寄存器外,还有32个128位的浮点寄存器,标记为V0至V31。这些寄存器用于以下目的:
- 存储标量浮点指令的浮点操作数。
- 存储NEON(ARM的高级SIMD(单指令多数据))操作的标量和向量操作数。
NEON技术允许进行高效的多媒体和浮点运算,这些运算在图形、音频、视频、科学计算和许多其他应用程序中非常重要。这些128位寄存器在NEON指令中可以被当作一个128位的单一寄存器使用,或者在某些操作中被分为较小的寄存器组,例如两个64位寄存器或四个32位寄存器。这些浮点寄存器和NEON技术在ARMv8架构的AArch64执行状态下提供了强大的处理能力,特别是在需要大量数学和逻辑运算的应用程序中。
4.6.1 AArch64中浮点寄存器的组织结构
在NEON和操作标量数据的浮点指令中,浮点寄存器和NEON寄存器的表现类似于主要的通用整数寄存器。因此,只有低位有效位被访问,高位未使用的位在读取时被忽略,在写入时被设置为零。标量浮点和NEON的命名约定如下,其中n是一个0到31的寄存器编号:
- 当使用标量浮点指令时,只有寄存器的低64位被使用。例如,如果使用
S0
进行操作,那么只有V0
寄存器的低64位被读取或写入。 - 对于NEON标量操作,可以指定使用寄存器的不同部分,例如使用
D0
的低64位或D0
的高64位(如果指令支持这种操作)。 - 在某些情况下,可以使用
S
或D
前缀来明确指出操作是针对单精度(32位)或双精度(64位)浮点数。
注意,ARMv8架构支持16位浮点数格式,但仅作为需要从该格式转换或转换到该格式的情况。它不支持将16位浮点数用于数据处理操作。
4.6.2 标量寄存器大小
在ARMv8架构中,寄存器的组织方式允许不同宽度的视图,以适应不同精度的操作。以下是一些关键点,解释了如何在不同的NEON和浮点指令中使用这些寄存器:
-
S0作为D0的低半部分:在图4中,S0是D0的低32位,而D0本身是Q0的低64位。这种模式对于S1、D1、Q1等也是类似的。
-
Q寄存器的低64位:每个Q寄存器的低64位可以被视为D0-D31,这是32个64位宽的寄存器,用于浮点和NEON操作。
-
Q寄存器的低32位:每个Q寄存器的低32位可以被视为S0-S31,这是32个32位宽的寄存器,同样用于浮点和NEON操作。
-
S寄存器的低16位:每个S寄存器的低16位可以被视为H0-H31,这是32个16位宽的寄存器,用于浮点和NEON操作。
-
H寄存器的低8位:每个H寄存器的低8位可以被视为B0-B31,这是32个8位宽的寄存器,仅用于NEON操作。
这种设计简化了编译器自动向量化高级代码的问题,因为它提供了一种自然的映射,使得标量代码更容易转换为NEON SIMD指令。例如,如果编译器识别到一个循环可以并行化,它可以将32个标量操作映射到NEON的128位寄存器上,每个寄存器可以容纳多个数据元素,从而实现更高效的数据处理。
此外,这种设计还允许程序员在编写汇编代码或低级代码时有更多的灵活性,因为他们可以选择适当的寄存器大小来匹配他们的数据类型和操作需求。这种灵活性对于优化性能和资源使用非常关键。
注意:
- 在每种情况下,只使用每个寄存器集的最低位。其余的寄存器空间在读取时被忽略,在写入时用零填充。
这个映射的一个后果是,如果一个在AArch64下执行的程序正在解释来自AArch32执行的D或S寄存器,那么程序必须在使用这些寄存器之前,将D或S寄存器从V寄存器中解包出来。
4.6.3 向量寄存器大小
向量可以是64位宽,包含一个或多个元素,也可以是128位宽,包含两个或多个元素。
4.6.4 NEON在AArch32执行状态
在AArch32中,较小的寄存器被打包进较大的寄存器中(例如,D0和D1组合成Q1)。这引入了一些棘手的循环携带依赖性,这可能会降低编译器向量化循环结构的能力。
在AArch32中,浮点和高级SIMD(NEON)寄存器被映射到AArch64的FP(浮点)和SIMD寄存器。这样做的目的是允许系统软件的更高层次,例如操作系统(OS)或虚拟机监视器(Hypervisor),来解释(并在必要时修改)应用程序或虚拟机的浮点和NEON寄存器。
AArch64的V16-V31浮点和NEON寄存器在AArch32中是不可见的。与通用寄存器一样,在AArch32执行异常级别期间,这些寄存器保留着之前使用AArch64执行时的状态。
相关文章:

【ARM】v8架构programmer guide(4)_ARMv8的寄存器
目录 4.4Endianness(端序或字节序) 4.5 改变execution state 4.5.1 Registers at AArch32 4.5.2 PSTATE at AArch32 4.6 NEON 和浮点数寄存器 4.6.1 AArch64中浮点寄存器的组织结构 4.6.2 标量寄存器大小 4.6.3 向量寄存器大小 4.6.4 NEON在AArc…...
Java设计模式详细讲解
目录 设计模式概述 1.1 什么是设计模式1.2 设计模式的类型1.3 设计模式的历史与发展1.4 设计模式在软件开发中的重要性 创建型模式 2.1 单例模式2.2 工厂方法模式2.3 抽象工厂模式2.4 建造者模式2.5 原型模式 结构型模式 3.1 适配器模式3.2 装饰器模式3.3 代理模式3.4 外观模…...
图论------弗洛伊德(Floyd-Warshall)算法
题目描述: 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的 T-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助…...
C#实现动画效果
在C#中,实现动画效果通常可以使用Windows Forms的Timer类或者使用System.Windows.Media.Animation命名空间下的类(如果是WPF应用)。以下是一个Windows Forms应用中使用Timer类来创建简单的动画效果的例子。 假设我们有一个窗体(F…...
Git 对比 SVN 的区别和优势
引言 版本控制系统(VCS)是软件开发过程中不可或缺的一部分,它们用于管理代码的变更、协调开发团队的工作。Git 和 SVN(Apache Subversion)是目前最流行的两个版本控制系统。本文将详细分析 Git 和 SVN 的区别及各自的…...
Qt实现无边框窗口的拖动和缩放
在使用QT创建窗体的时候,为了使窗口美化,通常不使用QT自带的边框。会调用下面函数去除窗体边框。 setWindowFlags(Qt::FramelessWindowHint) 但是有个问题,当去除了QT自带边框后,窗体就变得不能移动了,也不能改变窗口大…...

入门岛2-python实现wordcount并进行云端debug
书生大模型学习 任务: 1.实现一个wordcount函数,统计英文字符串中每个单词出现的次数。返回一个字典,key为单词,value为对应单词出现的次数。 2.Vscode连接InternStudio debug TIPS:记得先去掉标点符号,然后把每个单词…...

c语言-链表1
10 链表 一、链表是什么? -- 数据的一种存储方式 -- 链式存储 (1)线性存储 -- 地址连续 -- 自动开辟,自动释放 -- 默认是线性存储 (2)链式存储 -- 地址不连续…...

你好! Git——企业级开发模型
企业级开发模型(6) 一、删除远程分支,git branch -a (查看所有本地分支与远程分支)还能看到已经删除的分支,怎么解决?二、企业级开发流程2.1 企业级开发流程2.2 系统开发环境 三、Git分支设计模…...

力扣面试150 查找和最小的 K 对数字 最小堆 去重
Problem: 373. 查找和最小的 K 对数字 👨🏫 参考题解 class Solution {public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {// 创建一个大小为 k 的结果列表,用于存储和最小的 k 个数对List<Li…...
Oceanbase 执行计划
test100 CREATE TABLE `test100` ( `GRNT_CTR_NO` varchar(32) COLLATE utf8mb4_bin NOT NULL COMMENT 担保合同编号, `GRNT_CTR_TYP` varchar(3) COLLATE utf8mb4_bin NOT NULL COMMENT 担保合同类型, `COLC_GRNT_IND` varchar(1) COLLATE utf8mb4_bin DEFAULT NULL …...

精品丨模型关系介绍
PowerBI中的模型关系相信小伙伴们都不会感觉到陌生,因为一份优秀的报表无法离开数据模型的支撑。 对比其它BI类工具而言,白茶认为其建模功能才是最为突出的功能点。 模型关系类型 PowerBI中我们常用的模型关系一共包含5类: 一对一关系(1:1) …...

CentOS7 配置 nginx 和 php 方案
配置方案 一、安装软件二、编写配置文件,连接PHP三、引用文件四、测试 鉴于网上教程错综复杂,写下一这篇文章 本教程只需要三步即可 一、安装软件 yum install -y nginx php php-fpm二、编写配置文件,连接PHP 一般情况下在安装完 nginx 后…...
Promise.all全面解析:使用方法与实战技巧
Promise是JavaScript中处理异步操作的重要机制,它提供了一种优雅的方式来处理异步回调,避免了传统回调地狱的问题。而Promise.all作为Promise的一个静态方法,更是在处理多个异步操作时发挥着关键作用。本文将全面解析Promise.all的使用方法&a…...
NLP从零开始------9文本进阶处理之文本相似度计算
1.文本相似度计算简介 在自然语言处理中,经常会涉及度量两个文本相似度的问题。在诸如对话系统和信息减速等中,度量句子或短语之间的相似度尤为重要。在新闻学传媒中应用文本相似度可以帮助读者快速检索到想要了解的报道。 文本相似度的定义式如下所示&a…...
Electron 在 MAC 上的 build 签名应用配置
Electron 在 MAC 上的 build 签名应用配置涉及多个步骤,包括准备开发者账号、生成证书和配置文件、配置环境变量以及使用适当的工具进行签名和公证。以下是一个详细的配置流程: 一、准备开发者账号 首先,你需要在 Apple 开发者网站 注册并拥有一个开发者账号。这个账号将用…...
15 交换机命令行配置
交换机命令行配置 一、交换机命令行基本配置 (一)配置主机名 Switch>enable Switch#configure terminal Switch(config)#hostname S1(二)查看配置信息 Switch#show running-config Building configuration...Current confi…...

工作流之Flowable与SpringBoot结合
文章目录 1 Flowable1.1 flowable-ui部署运行1.2 绘制流程图1.2.1 绘制1.2.2 绘图细节1.2.3 bpmn文件导入 1.3 后台项目搭建1.3.1 pom.xml1.3.2 数据库表说明 1.4 流程引擎API与服务1.4.1 主要API1.4.2 示例 1 Flowable 1.1 flowable-ui部署运行 flowable-6.6.0 运行 官方dem…...
python实战:数据分析基础知识
当涉及到数据分析和统计建模时,Python 提供了强大的工具和库,如 pandas、numpy、statsmodels 和 matplotlib。本文将以一个实际的案例为例,介绍如何利用这些工具进行回归分析,并通过可视化工具进行结果展示和解释。 1. 背景介绍 …...
Grafana深入讲解
Grafana 深入讲解 目录 概述Grafana 基本概念 2.1 Grafana 简介2.2 Grafana 功能特性2.3 Grafana 架构 Grafana 安装与配置 3.1 安装 Grafana3.2 配置 Grafana3.3 验证 Grafana 安装 Grafana 数据源 4.1 支持的数据源类型4.2 添加数据源4.3 配置 Prometheus 数据源 Grafana 仪…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...