CPU Registers

A register is basically an n-bit binary storage element. CPU registers are usually used to temporarily hold data and memory address values that might be required in the near future. Since registers are located within the CPU, they can be accessed more quickly and more efficiently than external memory. Furthermore, since the number of registers is relatively small, operand specifiers need only be a few bits, as compared to memory addresses that require considerably more bits to represent. For instance, a 32-bit ARM instruction code includes two or three 4-bit operand specifiers, each of which identifies one of 16 registers (R0-R15) to be used as operands. On the other hand, ARM memory addresses are 32-bit each, so it is not possible to include a memory address within a 32-bit instruction code.

Each instruction set architecture has its own distinctive set of program accessible registers that may be used to store data, addresses, and control or status information. Examples of register sets of some of the commonly used microprocessors are shown in the following figures:

Register sets of 8051/8052
Figure 1.0 Register sets of 8051/8052

Register sets of Freescale HCS12 are illustrated below:

Register sets of Freescale HCS12
Figure 1.1 Register sets of Freescale HCS12

Register sets of Intel Pentium are shown in the figure below:

Register sets of Intel Pentium
Figure 1.2 Register sets of Intel Pentium

Register sets of ARM are illustrated below:

Register sets of ARM
Figure 1.3 Register sets of ARM

Each CPU includes one register called a program counter (PC) or instruction pointer (IP) that often contains the addresses in the memory of the next program instruction to be executed. The PC/IP register is updated automatically as each instruction is executed, so that it points to the next instruction to be fetched from memory.

One or more CPU registers are available to the programmer to hold memory addresses or information used to compute addresses. All 16 ARM registers (R0-R15) can hold either data or addresses. Equally, Pentium registers EBX, ESI, EDI, and EBP can be used for both addresses and data. Contrariwise, 8-bit microcontrollers and 16-bit microcontrollers typically have limited memory-addressing capabilities. For instance, the HCS12 has only two registers, index registers X and Y that can be used in memory addressing.

In 8051 and HCS12 microcontrollers the arithmetic and logic operations utilize accumulator registers, that is, registers in which results are “accumulated”. The 8051 has a single accumulator labelled A, in Figure 1.0 and the HCS12 has two accumulators, labelled A and B in Figure 1.1 above. In the HCS12, the two 8-bit accumulators can be concatenated into a double accumulator, labelled D in as illustrated in Figure 1.1, for 16-bit operations. Arithmetic operations such as addition and subtraction combine the number in the accumulator with a second operand and write the result back to the accumulator, overwriting the original accumulator contents. The second operand can be an immediate value or the contents of another register or memory location. To combine two data values from memory, one of them must be moved to the accumulator prior to the operation. After the operation, the result can be moved to a memory location if desired. In the HCS12, most instructions can use either the A or the B accumulator, and the A and B accumulators can be used together as a single 16-bit accumulator, referred to as register D.

Pentium and ARM CPUs give more flexibility to a programmer by providing a number of general-purpose registers, any of which can supply operands for, or receive the results of, arithmetic and logical operations. In the ARM, any of its 16 registers, 32 bits each, R0-R15, may be a source and or a destination in any instruction. In the same way, the Pentium provides eight general-purpose registers that can be used as operand sources/destinations. Pentium supports 8-bit, 16-bit, and 32-bit ALU operations, using the corresponding register names. For instance, an 8-bit operation may use the AL or AH register, a 16-bit operation the AX register, and a 32-bit operation the EAX register. All the four are located within the same 32-bit register. AL is the low 8 bits, AH the next 8 bits, and AX, the low 16 bits of the EAX register. (Refer to Figure 1.2 above for more details on these four types).

The following illustrates 8-bit, 16-bit and 32-bit addition operations in the Pentium CPU; the data size is implied by the register names:

ADD AL,BH    ;AL  +  BH → AL (8-bit bytes)

ADD AX,BX    ;AX + BX → AX (16-bit words)

ADD EAX,EBX  ;EAX + EBX → EAX (32-bit long words)

Whereas the eight Pentium general registers can be used in all arithmetic and logical operations, most of these registers also have additional special functions and are named accordingly. The four general-purpose registers EAX, EBX, ECX, and EDX are used by some instructions as an accumulator, a base address register, a count register, and an I/O-addressing register, respectively. The four index and pointer registers ESI, EDI, ESP, and EBP are used in memory addressing. Each half of the four general registers can be used independently in 8-bit operations, and thus the high and low parts of these registers are labelled AH/AL, BH/BL, CH/CL, and DH/DL.

Most CPUs include a processor status register (PSR), sometimes called condition code register that contains information about the internal CPU conditions and about ALU operations that have been performed. PSRs typically involve one or more condition code bits, or flags, which characterize the result of a previous arithmetic or logical operation performed in the ALU. These allow decisions to be made based on the outcomes of these operations. The table below lists the condition code flags of the HCS12, which are typical of those found in most CPUs. The half carry flag is used to support operations on BCD values, representing a carry from one decimal digit to the next within a byte.

Table HCS12 Condition Code Flags

FlagStatus of Last Result if Flag = 1
Z (Zero)Result zero
N (Sign)Result negative
C (Carry)Carry out of the most significant bit of the result
V (Overflow)Result out of range for the given number of bits
H (Half Carry)Carry from bit 3 to bit 4 of result

In addition to the regular memory addressing, most CPUs support a special last-in/fast-out data structure in memory referred to as a push-down stack. A stack is a convenient pace to temporarily save information and subsequently restore it. A CPU running a program may be temporarily interrupted to execute some other program. The state of the running program is saved temporarily on a stack while the other program is executed, and then restored from the stack when that program is completed, allowing the original program to resume where it left out.

A dedicated stack pointer (SP) register contains the address of the top element on the stack. An operation called PUSH adds an element to the stack, and an operation called POP or PULL removes an element from the stack as demonstrated in Figure 1.4 below.

Push-down stack PUSH and POP Operations
Figure 1.4 Push-down stack PUSH and POP Operations

The SP automatically increments and decrements as elements are added to and removed from the stack. ARM does not have dedicated PUSH/PULL instructions, however, the memory-addressing capabilities of the memory load and store instructions can perform basic stack operations, using any of the 16 registers as an SP. In place of a stack, ARM saves its program counter and the current PSR in registers R14 and SPSR (saved processor status register), respectively, for subroutine calls and interrupts.

A constant to be used as an operand for an instruction may be encoded directly within the instruction as the operand specifier. Such a data value is referred to as an immediate operand, because it is immediately available to the CPU from the fetched instructions, without having to access additional storage locations. The following example, demonstrates the instructions that add the immediate operand #5 to a designated CPU register.

8051: ADD A,#5     ;A + 5 → A

HCS12: ADDA #5    ;ACCA + 5 → ACCA

Pentium: ADD EAX,5  ;EAX + 5 → EAX

ARM: ADD R1,R2,#5    ;R2 + 5 → R1

Generally, immediate values are encoded with the same number of bits as the other operand(s) of the instruction, and appended to the instruction code. In ARM and other RISC processors, nevertheless, all instructions are encoded in 32-bits, which must include the opcode and all operand specifiers. Thus ARM limits an immediate operand to an 8-bit value, with an optional left or right shift. This value will be extended by the CPU to 32 bits before performing the operation.

Related: Beginner’s Step-by-Step Coding Course: Learn Computer Programming the Easy Way 

Please follow us and share:

Author: John Mulindi

John Mulindi has a background in a technical field and he writes on topics ranging from automation, computer systems, embedded systems, mechatronics to measurement and control.

2 thoughts on “CPU Registers”

Leave a Reply