Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Zero Register 'zr' in aarch64 essentially ground?

Recently started messing with AArch64 assembly and I noticed that it has an assigned register strictly for zero, whereas (most) other architectures you would just xor var, var.

The site I was reading about zr explained it as a reference point for zero which sounds a lot like how I define ground in DC electronics. And because ARM is used by hobbyists, tying ground in the circuit to zero in the code kinda makes sense to me.

I'm sure it's much more complex than this, but is this a safe analogy to make? And would using this register compared to other ways of getting '0' result in different outcomes?

like image 342
Mungoid Avatar asked Sep 19 '18 16:09

Mungoid


2 Answers

The zero register xzr resp. wzr is a cute design trick in the Aarch64 ISA. It's register number is 31, just as the stack pointer sp resp. wsp. Depending on the context, register number 31 refers to one of them.

This cute trick allows the Aarch64 ISA to simplify its instruction set. For example, the cmp xn, xm instruction is actually subs xzr, xn, xm, i.e. it's a subtract with the result being discarded. A mov xn, xm is simply an orr xn, xzr, xm. Register 31 is only recognised as the stack pointer where it makes sense and the instruction set has been cleverly chosen so you almost never hit this detail.

like image 168
fuz Avatar answered Oct 03 '22 23:10

fuz


Is Zero Register 'zr' in aarch64 essentially ground? ... is this a safe analogy to make?

No. There are all sorts of hardware logic out there. Whether the zero register's bits are connected to ground or not is unimportant since it's just an implementation detail. You only need to think of it as the numeric value zero and what happens if we read or write that register. Don't think about the underlying circuits when you're working in software

For example many architectures might use inverted logic (active-low) with 0V means logic 1, then the zero register will actually connect to Vcc. Or some others use balanced logic where logic 0 and 1 are represented by −Vcc and Vcc respectively. In that case the zero register will be connected to −Vcc and it's not ground either.


But why have a zero register?

The general RISC philosophy is to avoid memory access in every instruction, instead only load/store instructions are allowed to touch memory. As a result, RISC architectures need a lot of registers to reduce the need to spill to memory.

Pretty much every other RISC architectures has at least 32 registers, therefore it's worth dedicating one for the zero constant. We can see that: SPARC has %g0, MIPS has $zero or $0, Itanium (strictly speaking not RISC but VLIW, but still tons of registers [128]) has r0, RISC-V has x0, SH-5 has R63, Blackfin has R0, i860 has R0, PA-RISC has R0, ARC has %r0, Motorola 88000 has r0, Alpha with 2 separate zero registers: integer R31 and floating-point F31...

A slight deviation is PowerPC where r0 means either the GPR0 or the number 0 depending on instructions. However Plan 9 for PowerPC diverges even further by initializing r0 to 0 by software

  • Why the %r0 of SPARC or MIPS, is always 0?
  • How does a zero register improve performance?
  • Why MIPS uses R0 as "zero" when you could just XOR two registers to produce 0?

The only odd RISC architecture with 32 registers but without a zero register is Intel i960, but again the bizarre Plan 9 also requires the R3 register to be set to 0 by software. Another weird beast is OpenRISC where R0 is also initialized to 0 by software. This means that R0 should not be used as a destination because writes to it will destroy the value

The register 0 allows designers to remove many instructions, simplifying the hardware. For example we don't need mov any more, instead we can just add with zero and store in the destination. Negation is also now just a subtraction from zero. Writes to the zero register discard the results, and we don't need a separate NOP either. ARM and Intel i960 don't have a zero register so they have explicit mov instructions in the ISA

ARM was always an exception because it has only 16 registers (actually ~12-13, since SP, PC... are included in the general purpose set), making an exclusive register for zero wasteful. Moreover ARM wasn't considered pure RISC because its instructions and addressing modes are too complex (LDM, STM, shift and conditional in every instructions...)

Even though the ARM is a RISC architecture, it does not strictly follow the RISC principles as does the MIPS. For example, some of the ARM instructions such as ldm and stm are not simple instructions. In addition, it provides a large number of addressing modes and uses a somewhat complex instruction format

Guide to RISC Processors: for Programmers and Engineers

When Arm Holdings decided that Aarch64 would also have 32 registers, they'd definitely do the same thing to make the instruction set more RISCy and less orthogonal. Now the PC, SP... are also separated, thus we have more than twice the registers compared to ARM. There's no reason they don't do like others to make the hardware more complex

A similar case is the SuperH architecture, where the version SH-4 has 16 registers. When Renesas extended to it to 64 registers in SH-5 they also reserved R63 for the zero constant

like image 30
phuclv Avatar answered Oct 03 '22 23:10

phuclv