Why the %r0 of SPARC or MIPS, is always 0?

前端 未结 2 442
夕颜
夕颜 2021-01-06 22:03

I know that when you read %r0 in SPARC CPU (and MIPS), always return 0, but I like to know Why ?

What design decision is behind this and why ?

相关标签:
2条回答
  • 2021-01-06 22:44

    It's just the way the CPU was designed. Ensuring that r0 is always set to zero is, for one thing, a way to avoid potentially costly memory accesses for a very common value.

    On one hand (reading), it's handy to have a register set aside to contain the value of zero so that you can use it. Otherwise, you would have to load zero into a register yourself.

    Many RISC processors tend to favour data manipulation in registers, accessing memory only for load and store operations. That's not a hard and fast rule of RISC, more of a tendency. Setting aside a register so that you always have zero available can be useful - it's a trade-off since you get one less register to use for general purpose values but the MIPS designers obviously thought it was worth it.

    On the other hand (writing), because r0 is tied to the value zero, you can put what you want in there and it will make no difference - it will remain at zero. That means you can use it as a target if you want to throw the value away.

    Again, this has to do with the philosophy behind RISC. It tends to favour a very small number of instruction formats such as the MIPS R, I and J formats (register, immediate and jump). As an example, rather than having multiple instruction formats depending on whether you want to store the result or not, you can have one set which stores the result always, then just store it into r0 if you don't care about it.

    Hence, if you wanted to check if adding two registers would result in an overflow but didn't want to store the result anywhere, you could use:

    add $0, $7, $8  ; r0 <- r7 + r8, but r0 remains at 0.
    

    The MIPS documentation, MIPS32 Architecture for Programmers Volume I: Introduction to the MIPS32 Architecture, confirms the above:

    R0 is hard-wired to a value of zero, and can be used as the target register for any instruction whose result is to be discarded. R0 can also be used as a source when a zero value is needed.

    0 讨论(0)
  • 2021-01-06 22:49

    The main reason from instruction-set-design point of view is that the existance of a /dev/null-register allows for certain "condensing" of what otherwise would have to be two (or more) different instructions into a single one. Few examples:

    • function call and return, using link registers, can be done with a single instruction:
      • As function call instruction: jmp <tgtreg>,<pc>,<linkreg>
        (SPARC jmp is an atomic mov <pc>,<linkreg>; mov <tgtreg>,<pc>), and
      • As function return instruction: jmp <linkreg>,<nullreg>,<nullreg>
    • cmp or tst can be a simple sub <a>,<b>,<nullreg>

    Complete tables of these can be found from Oracle's documentation, SPARC synthetic instructions and sparcv9 synthetic instructions; most of these involve %g0 somewhere.

    0 讨论(0)
提交回复
热议问题