我最近在研究RISC-V 32I指令。我对NOP指令有一个问题,规范说它等同于ADDI x0,x0,0。
然而,x0不是程序员可以修改的通用寄存器。因此,为什么x0在这里作为NOP指令的目标寄存器?
请问有人能解释一下这个问题吗?
然而,x0不是程序员可以修改的通用寄存器。因此,为什么x0在这里作为NOP指令的目标寄存器?
请问有人能解释一下这个问题吗?
NOP
是一个伪指令,其展开为 ADDI x0, x0, 0
。 x0
(或zero
)是一个只读寄存器,专门用于存储值零,即每一位都硬连到0。无论写入该寄存器的内容如何,都将被丢弃,因为它的值不能被修改。
来自The RISC-V Instruction Set Manual Volume I: Unprivileged ISA:
NOP
指令不会改变任何架构可见状态,除了将pc
前进并增加任何适用的性能计数器。NOP
的编码为ADDI x0,x0,0
。
请记住,RISC-V没有算术标志(即进位、溢出、零、符号标志),任何算术操作的目标寄存器是 x0
都可以作为 no operation 指令,而不管源寄存器是什么,因为其净结果将包括将程序计数器推进到下一条指令而不更改任何其他相关处理器状态。
牛嘴鸟引用了一个正确的声明,x0保持常量0,不能被写入另一个值。
指令ADDI x0,x0,0
执行x0 <- x0 + 0
,其中0是编码在指令中的立即数。这种指令对RISCV的状态没有影响,因此是NOP。
RISCV上其他NOP的替代方法: ADDI x0, x1, 0
。即使ADD x0, x1, x2
也不会对RISCV产生影响(RISCV上没有进位标志),因此像NOP
一样运行。
x1
作为源,将会引入一个错误的依赖关系,这会导致nop
指令在最后一条写入x1
的指令执行完之前无法执行,除非硬件特别将其视为真正的nop
。从架构上来说,它当然还是一个NOP指令,但从微架构上来看,在超标量(和/或乱序)核心上可能会更糟糕。 - Peter Cordeshttps://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md
或者在https://riscv.org/specifications/的第109页上。
寄存器x0被硬连线到零。