唯一一个有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的一些指令,如ldm、stm,就不是简单指令,而且它提供了大量的寻址模式,使用了比较复杂的指令格式 RISC处理器指南:面向程序员和工程师 当Arm Holdings决定Aarch 64也有32个寄存器时,他们肯定会做同样的事情,使指令集更加精简和less orthogonal。现在PC、SP......也是分离的,因此我们的寄存器是ARM的两倍多。他们没有理由不像其他人那样使硬件更加复杂 类似的情况是SuperH架构,其中版本SH-4有16个寄存器。当Renesas在SH-5中将其扩展到64个寄存器时,他们还为零常数保留了R63
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
5条答案
按热度按时间brgchamk1#
零寄存器
xzr
和wzr
是Aarch64 ISA中的一个可爱的设计技巧。它的寄存器号是31,就像堆栈指针sp
和wsp
一样。根据上下文,寄存器号31指向其中之一。这一巧妙的技巧使得Aarch64伊萨简化了指令集。例如,
cmp xn, xm
指令实际上是subs xzr, xn, xm
,也就是说,它是一个结果被丢弃的减法。mov xn, xm
只是一个orr xn, xzr, xm
。即源与零的逐位或。寄存器31仅在有意义的情况下被识别为堆栈指针,并且指令集经过了巧妙的选择,因此您几乎不会遇到此限制。qxgroojn2#
aarch 64中的零寄存器“zr”本质上是接地的吗?......这是一个安全的类比吗?
不可以。硬件逻辑有很多种。零寄存器的位是否接地并不重要,因为这只是 * 实现细节*。您只需将其视为数值零,以及读取或写入该寄存器时会发生什么。在软件中工作时,不要考虑底层电路
例如,许多架构可能使用反相逻辑(低电平有效),0 V表示逻辑1,则zero寄存器实际上将连接到Vcc。或者,一些其他架构使用平衡逻辑,其中逻辑0和1分别由−Vcc和Vcc表示。在这种情况下,zero寄存器将连接到−Vcc,并且也不接地。
但为什么有一个零寄存器呢?
一般RISC的基本原理是 * 避免在每条指令中访问内存 *,而只允许加载/存储指令访问内存。因此,RISC架构需要 * 大量 * 寄存器来减少溢出到内存的需要。
几乎所有其他RISC架构都有至少32个寄存器,因此值得专门为零常数指定一个寄存器。SPARC具有
%g0
,MIPS具有$zero
或$0
,Itanium(严格地说不是RISC而是VLIW,但仍然是大量的寄存器[128])具有r0
,RISC-V具有x0
,SH-5具有R63,Blackfin具有R0
,i860具有R0
,PA-RISC具有R0
,ARC具有%r0
,Motorola 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的一些指令,如
ldm
、stm
,就不是简单指令,而且它提供了大量的寻址模式,使用了比较复杂的指令格式RISC处理器指南:面向程序员和工程师
当Arm Holdings决定Aarch 64也有32个寄存器时,他们肯定会做同样的事情,使指令集更加精简和less orthogonal。现在PC、SP......也是分离的,因此我们的寄存器是ARM的两倍多。他们没有理由不像其他人那样使硬件更加复杂
类似的情况是SuperH架构,其中版本SH-4有16个寄存器。当Renesas在SH-5中将其扩展到64个寄存器时,他们还为零常数保留了R63
oyjwcjzk3#
你可以把这个寄存器中的位看作是硬连线到地的,但是写入它并不会导致短路。一个更好的类比是Unix
/dev/zero
:将写入、读取作为零字节无限流丢弃。但是,它不是一个“参考”,因为它是相对于它来测量的。逻辑
0
位可以存在于CPU中,无论AArch 64是否有这个寄存器,它们都不会与它进行比较以确定它们是真/假。从电学上讲,逻辑1
通常是一个高电压,而0
=地,所以门确实会将它们的输入与地进行比较。并且任何地方的所有0
位都等效于地。(这可能是主要的过度简化,当然在ALU或其他东西内部,位可能被反转或物理上不存在,仅在一些其他表示中逻辑上存在)。因此,作为一个 * 类比 *,它根本不起作用。作为一个描述它是如何物理/电气实现的,它也不完全起作用。它需要在不短路的情况下丢弃写操作。在一个具有寄存器重命名的CPU中,它需要在RAT中使用特殊情况(寄存器分配表)来跟踪写操作被丢弃并且相关性链不通过
xzr
传播的事实。如果忽略这一点,你可以想象一个SRAM单元的替代品,输入端断开,输出端硬连线为零。它看起来像笨拙的措辞;更好的描述是零寄存器是静默地丢弃写入的固定常数。
阅读它会给你一个固定的常数零,这有时是有用的(例如,用于将零存储到存储器中,而不需要首先将寄存器清零)。除非上下文会给你相同寄存器编号的
sp
别名;我对AArch 64不是很了解6ju8rftf4#
要回答我认为是你的标题问题,不我不认为这是一个特别“安全”(有用)的类比。
电气工程中的接地概念具有非常特定的语义和许多相关概念,但与“固定零寄存器”只有非常相切的关系,因为数字零在两种情况下都涉及。
除了在两个概念中都存在零之外,我看不出这个类比有什么用。它几乎肯定不能反映寄存器是如何实现的,也不能让您将电气工程知识中的概念Map到ARM汇编编程中。如果您对零寄存器如何工作有疑问,(例如,“写时会发生什么?”),你似乎不太可能通过类比来回答这个问题。
我不知道为什么这个(未链接的)网站使用了*reference point这个术语来表示零,但是我认为完全忽略“reference point”这个术语是安全的。它就是零。当你读它的时候,它就是零,当你写它的时候,它什么也不做。这个术语的用处在fuz's answer中有解释。
总之,如果你发现这个类比对你来说是一个有用的心理结构,那么在你自己的学习过程中使用它是没有错的!
monwx1rj5#
Zr基本上接地
大部分是的。
下面的Verilog代码显示了一种典型的实现。
zr
总是连接到0
(即接地)。当软件代码试图写入zr
寄存器时,通过简单地忽略写入操作,低级硬件电路保持不变。