assembly aarch64中的零寄存器“zr”本质上是接地的吗?

fd3cxomn  于 2022-11-13  发布在  其他
关注(0)|答案(5)|浏览(272)

最近开始摆弄AArch64汇编,我注意到它有一个严格为 * 零 * 分配的寄存器,而(大多数)其他架构你只会xor var, var
我阅读的关于zr的网站将其解释为 * 零的参考点 *,这听起来很像我在直流电子产品中定义接地的方式。由于ARM是由业余爱好者使用的,因此在代码中将电路中的接地与零联系起来对我来说有点意义。
我相信它比这个复杂得多,但是这个类比安全吗?使用这个寄存器与其他获得“0”的方法相比会导致不同的结果吗?

brgchamk

brgchamk1#

零寄存器xzrwzr是Aarch64 ISA中的一个可爱的设计技巧。它的寄存器号是31,就像堆栈指针spwsp一样。根据上下文,寄存器号31指向其中之一。
这一巧妙的技巧使得Aarch64伊萨简化了指令集。例如,cmp xn, xm指令实际上是subs xzr, xn, xm,也就是说,它是一个结果被丢弃的减法。mov xn, xm只是一个orr xn, xzr, xm。即源与零的逐位或。寄存器31仅在有意义的情况下被识别为堆栈指针,并且指令集经过了巧妙的选择,因此您几乎不会遇到此限制。

qxgroojn

qxgroojn2#

aarch 64中的零寄存器“zr”本质上是接地的吗?......这是一个安全的类比吗?
不可以。硬件逻辑有很多种。零寄存器的位是否接地并不重要,因为这只是 * 实现细节*。您只需将其视为数值零,以及读取或写入该寄存器时会发生什么。在软件中工作时,不要考虑底层电路
例如,许多架构可能使用反相逻辑(低电平有效),0 V表示逻辑1,则zero寄存器实际上将连接到Vcc。或者,一些其他架构使用平衡逻辑,其中逻辑0和1分别由−Vcc和Vcc表示。在这种情况下,zero寄存器将连接到−Vcc,并且也不接地。
但为什么有一个零寄存器呢?
一般RISC的基本原理是 * 避免在每条指令中访问内存 *,而只允许加载/存储指令访问内存。因此,RISC架构需要 * 大量 * 寄存器来减少溢出到内存的需要。
几乎所有其他RISC架构都有至少32个寄存器,因此值得专门为零常数指定一个寄存器。SPARC具有%g0,MIPS具有$zero$0Itanium(严格地说不是RISC而是VLIW,但仍然是大量的寄存器[128])具有r0RISC-V具有x0SH-5具有R63Blackfin具有R0i860具有R0PA-RISC具有R0ARC具有%r0Motorola 88000具有r0,Alpha具有2个单独的零寄存器:整数R31和浮点F31...
PowerPC稍有不同,其中r0表示GPR 0或数字0,具体取决于指令。

唯一一个有32个寄存器但 * 没有零寄存器 * 的奇怪RISC架构是Inteli960,但同样奇怪的Plan 9也是requires the R3 register to be set to 0 by software。另一个奇怪的怪物是OpenRISC,其中R 0也被软件初始化为0。这意味着R 0不应被用作目的地,因为写入它会破坏值
寄存器0允许设计者删除许多指令,简化硬件。例如,我们不再需要mov,而是可以将add与零一起存储到目的地。求反现在也只是从零中减去。写入零寄存器将丢弃结果。ARM和Intel i960没有零寄存器,因此它们在伊萨中有显式的mov指令
ARM一直是个例外,因为它只有16个寄存器(实际上是~12-13个,因为SP、PC......都包含在通用寄存器集中),使得一个专用寄存器成为零浪费。此外,ARM不被认为是纯粹的RISC,因为它的指令和寻址模式太复杂(每个指令中的LDM、STM、移位和条件......)。
ARM虽然是RISC架构,但它并不像MIPS那样严格遵循RISC原则,比如ARM的一些指令,如ldmstm,就不是简单指令,而且它提供了大量的寻址模式,使用了比较复杂的指令格式
RISC处理器指南:面向程序员和工程师
当Arm Holdings决定Aarch 64也有32个寄存器时,他们肯定会做同样的事情,使指令集更加精简和less orthogonal。现在PC、SP......也是分离的,因此我们的寄存器是ARM的两倍多。他们没有理由不像其他人那样使硬件更加复杂
类似的情况是SuperH架构,其中版本SH-4有16个寄存器。当Renesas在SH-5中将其扩展到64个寄存器时,他们还为零常数保留了R63

oyjwcjzk

oyjwcjzk3#

你可以把这个寄存器中的位看作是硬连线到地的,但是写入它并不会导致短路。一个更好的类比是Unix /dev/zero:将写入、读取作为零字节无限流丢弃。
但是,它不是一个“参考”,因为它是相对于它来测量的。逻辑0位可以存在于CPU中,无论AArch 64是否有这个寄存器,它们都不会与它进行比较以确定它们是真/假。从电学上讲,逻辑1通常是一个高电压,而0 =地,所以门确实会将它们的输入与地进行比较。并且任何地方的所有0位都等效于地。(这可能是主要的过度简化,当然在ALU或其他东西内部,位可能被反转或物理上不存在,仅在一些其他表示中逻辑上存在)。
因此,作为一个 * 类比 *,它根本不起作用。作为一个描述它是如何物理/电气实现的,它也不完全起作用。它需要在不短路的情况下丢弃写操作。在一个具有寄存器重命名的CPU中,它需要在RAT中使用特殊情况(寄存器分配表)来跟踪写操作被丢弃并且相关性链不通过xzr传播的事实。如果忽略这一点,你可以想象一个SRAM单元的替代品,输入端断开,输出端硬连线为零。
它看起来像笨拙的措辞;更好的描述是零寄存器是静默地丢弃写入的固定常数。
阅读它会给你一个固定的常数零,这有时是有用的(例如,用于将零存储到存储器中,而不需要首先将寄存器清零)。除非上下文会给你相同寄存器编号的sp别名;我对AArch 64不是很了解

6ju8rftf

6ju8rftf4#

要回答我认为是你的标题问题,我不认为这是一个特别“安全”(有用)的类比。
电气工程中的接地概念具有非常特定的语义和许多相关概念,但与“固定零寄存器”只有非常相切的关系,因为数字零在两种情况下都涉及。
除了在两个概念中都存在零之外,我看不出这个类比有什么用。它几乎肯定不能反映寄存器是如何实现的,也不能让您将电气工程知识中的概念Map到ARM汇编编程中。如果您对零寄存器如何工作有疑问,(例如,“写时会发生什么?”),你似乎不太可能通过类比来回答这个问题。
我不知道为什么这个(未链接的)网站使用了*reference point这个术语来表示零,但是我认为完全忽略“reference point”这个术语是安全的。它就是零。当你读它的时候,它就是零,当你写它的时候,它什么也不做。这个术语的用处在fuz's answer中有解释。
总之,如果你发现这个类比对你来说是一个有用的心理结构,那么在你自己的学习过程中使用它是没有错的!

monwx1rj

monwx1rj5#

Zr基本上接地

大部分是的

下面的Verilog代码显示了一种典型的实现。zr总是连接到0(即接地)。当软件代码试图写入zr寄存器时,通过简单地忽略写入操作,低级硬件电路保持不变。

always@(posedge clk, negedge rst_n) begin
  if(~rst_n) begin // set initial value when reset released.
    zr <= 32'b0;
  end else if(re) begin // only respond to the read operation
    zr <= 32'b0;
end

相关问题