A processor register is a quickly accessible location available to a computer's processor. Registers usually consist of a small amount of fast storage, although some registers have specific hardware functions, and may be read-only or write-only.
Its used to store data, operands, calculation results, memory addressing, peripheral control, and microcontroller operation during instruction execution.

Each register has a specific function and bit capacity.
🟠 When performing an arithmetic operation, the processor may load the operands into general-purpose registers, perform the operation, and then store the result in another register or in memory.


📌 Why registers are important

  • They are the fastest way to access information and allow operations to be performed without accessing external RAM memory.
  • Almost every microprocessor command relies on the use of registers.
  • Setting up the microcontroller peripherals directly depends on writing to control registers.

🧩 Basic types of registers

Type Purpose Examples
General-purpose registers (GPR) * Stores data and intermediate values and adresses
* When adding numbers, the processor loads the values ​​from `RAM` into registers, performs the operation and stores the result back.
R0–R31 (AVR), EAX–EDX (x86), R0–R12 (ARM)
Special-purpose registers (SFR) * Hold some elements of the program state
* Each SFR has a **fixed address** in memory and is controlled by software
* They usually include the program counter, also called the instruction pointer
* Microcontrollers, can also have special function registers corresponding to specialized hardware elements.(timers, UART, ADC, etc.)
TCCR0, ADCSRA, USART_CR
Address Registers * Hold addresses and are used by instructions that indirectly access primary memory. SP, BP, SI, DI, X, Y, Z
Data Registers * Can hold numeric data values such as `integers` and, (in some architectures `floating-point` numbers), as well as `characters`, small `bit arrays` and other data for I/O PORTx, PINx, DDRx
Status (Flag) Registers
Condition code register (CCR)
* Contain bits of the flags of the operation result
* Hold truth values often used to determine whether some instruction should or should not be executed.
SREG, CPSR, FLAGS
Hardware registers * Used in the interface between software and peripherals * Input/output (I/O) of different kinds
* Configuration and start-up of certain features, especially during initialization
* Used to interact with physical pins of the microcontroller: reading/writing levels, configuring directions, etc.
Command registers (IP/PC)
* not accessible by instructions and are used internally for processor operations
Point to the currently executing instruction PC, EIP, R15
Segment registers
* not accessible by instructions and are used internally for processor operations
Point to memory segments (x86) CS, DS, SS, ES

🛠 Example: Setting up SysTick (ARM Cortex-M)

To manually set up the system timer (SysTick) three registers are used:

Register NamePurposeAddress
SYST_CSRControl and Status0xE000E010
SYST_RVRReset Value0xE000E014
SYST_CVRCurrent Value0xE000E018
  • The SYST_CSR register enables the SysTick features. It has three parameters that we are interested in:

    • clock source (which specifies what clock rates the timer should support),
    • tick interrupt enable (which allows an interrupt to fire when the timer reaches zero) and
    • enabling the timer itself
      The parameters are controlled by the three least significant bits in our 32-bit register.
      So for example, if you wanted to set all values ​​to one, our 32 bits would look like this. (00000000_00000000_00000000_000000111) The last three bits are set to one.
  • The SYST_RVR register specifies the start value to load into the SYST_CVR register.
    It counts down from that value to zero.
    It's a 24-bit register, so the total number of values ​​we have is about 16.7 million.

  • The SYST_CVR register contains the current value of the counter.
    If the timer restarted with a reset value of 250 and 100 ticks have passed, the current value will be 150.
    You can go to this register to clear the value.
    It is good practice to clear this register before enabling the timer so that its value makes sense when you read it.

Rust example:

const SYST_CSR: u32 = 0xE000E010;
const SYST_RVR: u32 = 0xE000E014;
const SYST_CVR: u32 = 0xE000E018;

let sleep_dur = CPU_FREQ; // duration = 1 second

unsafe {
    *(SYST_RVR as *mut u32) = sleep_dur;    // set timer duration
    *(SYST_CVR as *mut u32) = 0;            // set current value to 0
    *(SYST_CSR as *mut u32) = 0b111;        // set source, enable timer and interrupts
}