代码:
#define __ASM __asm /*!< asm keyword for ARM Compiler */ #define __INLINE __inline /*!< inline keyword for ARM Compiler */ #define __STATIC_INLINE static __inline /** \brief Set Priority Mask This function assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) { register uint32_t __regPriMask __ASM("primask"); __regPriMask = (priMask); }
参见armcc.chm文件9.155 Named register variables一节。
9.155 Named register variables
The compiler enables you to access registers of an ARM architecture-based processor or coprocessor using named register variables.
Syntax
register
type
var-name
__asm(reg
);
Where:
-
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.
type
var-name
reg
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, apart from Cortex-M series processors. |
BASEPRI | "basepri" | ARMv7-M processors |
BASEPRI_MAX | "basepri_max" | ARMv7-M processors |
CONTROL | "control" | ARMv6-M and ARMv7-M processors |
DSP | "dsp" | ARMv6-M and ARMv7-M processors |
EAPSR | "eapsr" | ARMv6-M and ARMv7-M processors |
EPSR | "epsr" | ARMv6-M and ARMv7-M processors |
FAULTMASK | "faultmask" | ARMv7-M processors |
IAPSR | "iapsr" | ARMv6-M and ARMv7-M processors |
IEPSR | "iepsr" | ARMv6-M and ARMv7-M processors |
IPSR | "ipsr" | ARMv6-M and ARMv7-M processors |
MSP | "msp" | ARMv6-M and ARMv7-M processors |
PRIMASK | "primask" | ARMv6-M and ARMv7-M processors |
PSP | "psp" | ARMv6-M and ARMv7-M processors |
PSR | "psr" | ARMv6-M and ARMv7-M processors |
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 |
SPSR |
"spsr"
| All processors, apart from Cortex-M series processors. |
XPSR | "xpsr" | ARMv6-M and ARMv7-M processors |
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" |
Note
Some registers are not available on some architectures.
Usage
You 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.
Note
A 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.Restrictions
Declaring 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.
Examples
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 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