assembly - armv8 中的 MOV 指令使用哪个处理器部分
问题描述
假设我有以下指令 - MOV X5, XZR
这条 MOV 伪指令将使用处理器硬件的哪一部分?我的意思是 - MOV 指令是否需要使用 ALU 或内存?这显然需要访问寄存器。
我很好奇,因为我正在阅读教科书“计算机组织与设计”,其中作者讨论了 2-issue 处理器。两条指令在同一个数据包中的要求是,如果一条指令是内存指令,那么另一条指令必须是 ALU/Logic 或分支。我上面提到的指令后面跟着一个分支指令,我不确定这两条指令是否可以在同一个数据包中。
如果您可以分享一些有关此伪指令实际实现方式的信息,那也将非常有帮助。谢谢你的帮助。
解决方案
XZR是一个寄存器的别名,它总是返回 0 并且只能更改为 0。它在 AArch64 中是新的,但其他 RISC (如 MIPS)总是有一个零寄存器。(32 位 ARM / Thumb ARMv8 模式是一些 AArch64 CPU 也可以执行的不同架构。)
寄存器不存在于内存中并且不涉及内存,除非指令将数据从内存移动到寄存器,反之亦然。
该指令基本上是通过将一个寄存器复制到另一个寄存器来将寄存器 X5 设置为零。
ARM 是整个“RISC”范式的一部分,但有一些实际的效率妥协。AArch64 使其更加 RISCy,删除了一些使现代超标量流水线复杂化的 ARM 东西,并将寄存器扩展到 64 位。该 RISC 范式的一些设计原则是:
- 提供了大量的寄存器。AArch64 有 32 个整数寄存器,高于 ARM 中的 15 个(不包括程序计数器)。(与当时的 x86 的 8 相比,这仍然很大)。
- 有指令可以将数据加载到寄存器或从寄存器存储数据(因此 RISC 也被称为“加载存储架构”)
- 其他指令(例如 ADD、SUB 等)仅在寄存器上工作 - 存在有限的寄存器与内存操作。因此,不使用“将内存位置 1000 的内容添加到寄存器 X”之类的内容 - 您必须“使用内存位置 1000 的内容加载 X2”然后“X = X + X2”。(
add reg, mem
甚至add mem,reg
是 RISC 避免的经典 CISC 功能。)
因此,鉴于遗留问题,您可能会将这条指令放在“ALU”类别中,因为它根本不与内存通信,而且它只在整数寄存器(而不是 FP/向量)上运行。就管道的其余部分而言,它只读写整数寄存器值,而不是内存,也不分支。
但是 ALU 在 CPU 上所做的是:ALU 接受输入,执行操作,然后将其传递到输出。在 RISC 中,输入总是寄存器。
使用 MOV,没有操作,输入只是简单地传递到输出。它可以绕过 ALU,或者为了简单起见,数据路径仍然通过带有控制信号的 ALU,使其执行类似于 OR 的操作,0
因此值不变。
如您所见,现实世界并不像您的教科书那么整洁。我不知道任何给定 ARM CPU 中的管道实际上是如何工作的。
推荐阅读
- c# - MongoDB C# 驱动程序发送到副本集成员的未指定端点
- ascii - 隐写术程序 - 将 python 2 转换为 3,语法错误:base64.b64decode("".join(chars))
- python - MQTT:无法同时在同一个文件中发送和接收消息
- javascript - 即使支持,speechSynthesis 也无法在移动 Safari 上运行
- etl - ETL架构中的数据流流程
- python - 如何使用 SQLAlchemy 和 FastAPI 中的 json.dumps 删除 json 输出中的额外反斜杠?
- haskell - 返回给定索引处元素的函数
- java - 使用 Azure AD 帐户时出现强制密码更改问题
- c# - ASP net core MVC 1种形式下调用不同动作
- java - Joda Time 返回正确的日期,但 Java 时间没有