9.149 Named register variables

The compiler enables you to access registers of an ARM architecture-based processor or coprocessor using named register variables.


register type var-name __asm(reg);
is the type of the named register variable.
Any type of the same size as the register being named can be used in the declaration of a named register variable. The type can be a structure, but bitfield layout is sensitive to endianness.
is the name of the named register variable.
is a character string denoting the name of a register on an ARM architecture-based processor, or for coprocessor registers, a string syntax that identifies the coprocessor and corresponds with how you intend to use the variable.
Registers available for use with named register variables on ARM architecture-based processors are shown in the following table.

Table 9-19 Named registers available on ARM architecture-based processors

Register Character string for __asm Processors
APSR "apsr" All processors
CPSR "cpsr" All processors
BASEPRI "basepri" Cortex-M3, Cortex-M4
BASEPRI_MAX "basepri_max" Cortex-M3, Cortex-M4
CONTROL "control" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
DSP "dsp" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
EAPSR "eapsr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
EPSR "epsr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
FAULTMASK "faultmask" Cortex-M3, Cortex-M4
IAPSR "iapsr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
IEPSR "iepsr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
IPSR "ipsr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
MSP "msp" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
PRIMASK "primask" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
PSP "psp" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
PSR "psr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
r0 to r12 "r0" to "r12" All processors
r13 or sp "r13" or "sp" All processors
r14 or lr "r14" or "lr" All processors
r15 or pc "r15" or "pc" All processors
All processors, apart from Cortex-M series processors.
XPSR "xpsr" Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4
On targets with floating-point hardware, the registers listed in the following table are also available for use with named register variables.

Table 9-20 Named registers available on targets with floating-point hardware

Register Character string for __asm
FPSID "fpsid"
FPSCR "fpscr"
FPEXC "fpexc"
FPINST "fpinst"
FPINST2 "fpinst2"
FPSR "fpsr"
MVFR0 "mvfr0"
MVFR1 "mvfr1"


Some registers are not available on some architectures.


You can declare named register variables as global variables. You can declare some, but not all, named register variables as local variables. In general, do not declare VFP registers and core registers as local variables. Do not declare caller-save registers, such as R0, as local variables.


In the following example, apsr is declared as a named register variable for the "apsr" register:
register unsigned int apsr __asm("apsr");
apsr = ~(~apsr | 0x40);
This generates the following instruction sequence:
MRS r0,APSR ; formerly CPSR
BIC r0,r0,#0x40
MSR CPSR_c, r0
In the following example, PMCR is declared as a register variable associated with coprocessor cp15, with CRn = c9, CRm = c12, opcode1 = 0, and opcode2 = 0, in an MCR or an MRC instruction:
register unsigned int PMCR __asm("cp15:0:c9:c12:0");
__inline void __reset_cycle_counter(void)
    PMCR = 4;
The disassembled output is as follows:
__reset_cycle_counter PROC
    MOV    r0,#4
    MCR    p15,#0x0,r0,c9,c12,#0
    BX     lr
In the following example, cp15_control is declared as a register variable for accessing a coprocessor register. This example enables the MMU using CP15:
register unsigned int cp15_control __asm("cp15:0:c1:c0:0");
cp15_control |= 0x1;
The following instruction sequence is generated:
MRC  p15,#0x0,r0,c1,c0,#0
ORR  r0,r0,#1
MCR  p15,#0x0,r0,c1,c0,#0
The following example for Cortex-M3 declares _msp, _control and _psp as named register variables to set up stack pointers:
register unsigned int _control __asm("control");
register unsigned int _msp     __asm("msp");
register unsigned int _psp     __asm("psp");void init(void)
  _msp = 0x30000000;        // set up Main Stack Pointer
  _control = _control | 3;  // switch to User Mode with Process Stack
  _psp = 0x40000000;        // set up Process Stack Pointer
This generates the following instruction sequence:
  MOV r0,#0x30000000
  MSR MSP,r0
  ORR r0,r0,#3
  MOV r0,#0x40000000
  MSR PSP,r0
  BX lr
Related concepts
3.12 Compiler support for accessing registers using named register variables
Non-ConfidentialPDF file icon PDF versionARM DUI0375E
Copyright © 2007, 2008, 2011, 2012, 2014 ARM. All rights reserved.