Skip to main content

Section 8.2 CPU Registers

A portion of the memory in the CPU is organized into registers. Machine instructions access CPU registers by their addresses, just as memory contents are accessed. Of course, the register addresses are not placed on the address bus since the registers are in the CPU. The difference from a programmer's point of view is that the assembler has predefined names for the registers, whereas the programmer creates symbolic names for memory addresses. Thus in each program that you write in assembly language:

  • CPU registers are accessed by using the names that are predefined in the assembler.

  • Memory is accessed by the programmer providing a name for the memory location and using that name in the user program.

Applications programmers have access to 16 integer registers in the AARCH32 (32-bit) state, r0r15. All but three are general purpose. The three special-purpose registers are affected by some instructions without their being explicitly named in the instruction. The r13 register holds the address of the top of the stack (Section 10.2). The r14 register holds the return address when a procedure is called (bl instruction). And the r15 register holds the address of the next instruction to be executed (Section 8.4).

Two of the general-purpose registers are commonly used in procedure call protocols, r11 as a reference point in the stack (this will be explained in Section 10.3 and r12 as a scratch register between procedure calls.

The names of the registers and their usage in AARCH32 state are summarized in Table 8.2.1.

Table 8.2.1. Application programming registers in ARM CPUs running a 32-bit operating system—AARCH32 state. See Table 8.0.1 for the CPUs used in different Raspberry Pi models.
Register Register
Name Number Usage
r0r10 \(0\)–\(10\) General Purpose
r11 or fp \(11\) Frame Pointer
r12 or ip \(12\) Intraprocess scratch
r13 or sp \(13\) Stack Pointer
r14 or lr \(14\) Link Register
r15 or pc \(15\) Program Counter

With the 64-bit architecture ARM introduced the terminology AARCH64 to indicate a CPU that is running in 64-bit state and AARCH32 to indicate 32-bit state. The Cortex-A53 in the Pi 3B (see Table 8.0.1) can be run in either state, but the CPUs in the other Raspberry Pis can only run in AARCH32 state.

In AARCH64 (64-bit) state applications programmers have access to 30 integer registers. The names of the registers and their usage in AARCH64 state are shown in Table 8.2.2. rn or xn, where \(n = 0, 1, \ldots , 30\text{,}\) refers to the entire 64 bits. Using wn, where \(n = 0, 1, \ldots , 30\text{,}\) refers to the low-order 32-bit portion of the register.

Table 8.2.2. Application programming registers in ARM CPUs running a 64-bit operating system—AARCH64 state. Using X30 is used as the link register. The use of xzr or wzr is interpreted as the value \(0\text{.}\) See Table 8.0.1 for the CPUs used in different Raspberry Pi models.
Full 64-bit Low 32-bit Register
Register Name Register Name Number Usage
r0r30 or x0x30 w0w30 \(0\)–\(30\) General Purpose
sp wsp \(31\) Stack Pointer
xzr wzr virtual Zero Register

The pc is not directly accessible to the applications programmer in AARCH64 state. The x30 register is used as the link register. If a program uses register wzr or xzr, that is interpreted to be the value \(0\text{,}\) but there is no physical register. The instruction is coded to supply a \(0\) where the value in the the zero register would be used.

The bits in a register are numbered from right to left, \(0\)–\(63\) for a 64-bit register and \(0\)–\(31\) for a 31-bit register. In AARCH64 state wn refers to bits \(31\)–\(0\) in register \(n\text{.}\) If an instruction reads these 32 bits from the register, bits \(63\)–\(32\) are ignored, and if an instruction writes to the 32 bits, bits \(63\)–\(32\) are set to zero.

As of this writing (July 2016) the Raspbian operating system is only available in a 32-bit version, so all the programs are 32-bit. There are some differences between the AARCH32 and AARCH64 instruction sets. I believe that most of the programs will work with only a little modification under a 64-bit version of Raspbian. But I do not have a way to test this, so I only provide the AARCH32 instructions in this book.

Many instructions can access one byte in a register, which consists of the bits \(7\)–\(0\) in the specified register. And accessing two bytes at a time works on bits \(15\)–\(0\) in the specified register. This is specified in the instruction, not in the register name.

In Chapter 3 you learned that the CPU includes a Current Program Status Register (CPSR) that includes the C and V flags. The ARM manual, ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition[1], describes three types of CPU status registers:

Current Program Status Register (CPSR)

Provides information about the currently executing program, both at an application level and a system level.

Application Program Status Register (APSR)

Provides a view of the CPSR that is restricted to the parts that are accessible at an application level.

Saved Program Status Registers (SPSRs)

Saved copies of the state of the CPSR when an exception occurs. There are seven, one for each execution mode. Exceptions will be explained in Chapter 17.

The format of the Current Program Status Register is shown if Figure 8.2.3.

Figure 8.2.3. Current Program Status Register (CPSR).

The APSR view of the CPSR only provides the following Condition Flags:

  • N, bit 31: Negative condition flag.

  • Z, bit 30: Zero condition flag.

  • C, bit 29: Carry condition flag.

  • V, bit 28: Overflow condition flag.

  • Q, bit 27: Overflow or saturation resulting from executing some instructions mostly related to digital signal processing.

  • GE, bits 19–16: Greater than or equal flags related to individual bytes or halfwords in parallel addition and subtraction instructions.

The condition flags are almost always used indirectly, so you do not need to memorize their location in the status registers. Most ARM instructions have the option to affect them or not. In the AARCH32 state, most ARM instructions include an option to implicitly test the condition flags and execute or not, based on the current state of the condition flags. This will be explained as the instructions are introduced in subsequent chapters. The conditional execution option does not exist in the AARCH64 state.