|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Technical Support On-Line Manuals Compiler User Guide ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Named register variables
9.153 Named register variablesThe compiler enables you to access registers of an ARM architecture-based processor or coprocessor using named register variables. Syntax
Where:
UsageYou must declare core registers as global rather than local named register
variables. Your program might still compile if you declare them locally, but you
risk unexpected runtime behavior if you do. There is no restriction on the scope of
named register variables for other registers.
NoteA global named register variable is global to the source file in which it is declared, not global to the program. It has no effect on other files, unless you use multifile compilation or you declare it in a header file.RestrictionsDeclaring a core register as a named register variable means that register is not
available to the compiler for other operations. If you declare too many named
register variables, code size increases significantly. In some cases, your program
might not compile, for example if there are insufficient registers available to
compute a particular expression.
Register usage defined by the Procedure Call Standard for the ARM
Architecture (AAPCS) is not affected by declaring named register
variables. For example,
r0 is always used to return result values
from functions even if it is declared as a named register variable.Named register variables are a compiler-only feature. With the exception of
r12 , tools such as linkers do not change register usage in
object files. The AAPCS reserves r12 as the inter-procedural
scratch register. You must not declare r12 as a named register
variable if you require its value to be preserved across function calls.ExamplesIn 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 ENDP 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:
init MOV r0,#0x30000000 MSR MSP,r0 MRS r0,CONTROL ORR r0,r0,#3 MSR CONTROL,r0 MOV r0,#0x40000000 MSR PSP,r0 BX lr Related information | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.