我知道当你在SPARC CPU(和MIPS)中读取%r0时,总是返回0,但我想知道为什么?
这背后有什么设计决定?为什么?
答案 0 :(得分:5)
这就是CPU的设计方式。确保r0
始终设置为零是一种方法,可以避免对非常常见的值进行可能代价高昂的内存访问。
一方面(阅读),将寄存器设置为包含零值以便您可以使用它是很方便的。否则,您必须自己将零加载到寄存器中。
许多RISC处理器倾向于支持寄存器中的数据操作,仅为加载和存储操作访问内存。这不是RISC的硬性规则,而是一种趋势。将寄存器放在一边以便始终保持零可用是有用的 - 这是一个权衡,因为你可以减少一个寄存器用于通用值,但MIPS设计者显然认为这是值得的。
另一方面(写作),因为r0
与零值相关联,你可以把你想要的东西放在那里,它没有任何区别 - 它将保持为零。这意味着如果你想抛弃价值,你可以将它用作目标。
同样,这与RISC背后的哲学有关。它倾向于支持极少数的指令格式,例如MIPS R
,I
和J
格式(寄存器,立即和跳转)。例如,根据您是否要存储结果而不是具有多种指令格式,您可以使用一组始终存储结果,然后将其存储到r0
中,如果您不关心它
因此,如果您想检查添加两个寄存器是否会导致溢出但不希望将结果存储在任何位置,您可以使用:
add $0, $7, $8 ; r0 <- r7 + r8, but r0 remains at 0.
MIPS文档MIPS32 Architecture for Programmers Volume I: Introduction to the MIPS32 Architecture
确认了上述内容:
R0硬连接到零值,并且可以用作要丢弃其结果的任何指令的目标寄存器。当需要零值时,R0也可以用作源。
答案 1 :(得分:1)
从指令集设计的角度来看,主要原因是/dev/null
- 寄存器的存在允许某些“凝聚”否则必须两个(或更多)不同的指令到单之一。几个例子:
call
和return
可以使用单个指令完成:
jmp <tgtreg>,<pc>,<linkreg>
jmp
是原子mov <pc>,<linkreg>; mov <tgtreg>,<pc>
)和jmp <linkreg>,<nullreg>,<nullreg>
cmp
或tst
可以是一个简单的sub <a>,<b>,<nullreg>
可以在Oracle的文档SPARC synthetic instructions和sparcv9 synthetic instructions中找到完整的表格。其中大部分涉及%g0
某处。