The variable can be thought of as a virtual register.
The compiler declares variables for physical registers as appropriate during optimization
and code generation. However, the physical register used in the assembled code might be
different to that specified in the instruction, or it might be stored on the stack. You can
explicitly declare variables representing physical registers as normal C or C++ variables.
The compiler implicitly declares registers R0
to R12
and
r0
to r12
as auto signed int
local variables, regardless of whether or not they are used. If you want to declare them to
be of a different data type, you can do so. For example, in the following code, the compiler
does not implicitly declare r1
and r2
as auto
signed int
because they are explicitly declared as
char
and float
types respectively:
void bar(float *);
int add(int x)
{
int a = 0;
char r1 = 0;
float r2 = 0.0;
bar(&r2);
__asm
{
ADD r1, a, #100
}
...
return r1;
}
The compiler does not implicitly declare variables for any other registers, so you must
explicitly declare variables for registers other than R0
to
R12
and r0
to r12
in your C or C++
code. No variables are declared for the sp
(r13
),
lr
(r14
), and pc
(r15
)
registers, and they cannot be read or directly modified in inline assembly code.
There is no virtual Processor Status Register (PSR). Any
references to the PSR
are always to the physical PSR
.
The size of the variables is the same as the physical registers.
The compiler-declared variables have function local scope, that is, within a single
function, multiple asm
statements or declarations that reference
the same variable name access the same virtual register.
Existing inline assembly code that conforms to previously documented guidelines continues
to perform the same function as in previous versions of the compiler, although the actual
registers used in each instruction might be different.
The initial value in each variable representing a physical register is UNKNOWN. You must write to these variables before reading
them. The compiler generates an error if you attempt to read such a variable before writing
to it, for example, if you attempt to read the variable associated with the physical
register r1
.
Any variables that you use in inline assembly code to refer to registers must be explicitly
declared in your C or C++ code, unless they are implicitly declared by the compiler.
However, it is better to explicitly declare them in your
C or C++ code. You do not have to declare them to be of the same data type as the implicit
declarations. For example, although the compiler implicitly declares register
R0
to be of type signed int
, you can explicitly
declare R0
as an unsigned integer variable if required.
It is also better to use C or C++ variables as instruction operands. The compiler generates
a warning the first time a variable or physical register name is used, regardless of whether
it is implicitly or explicitly declared, and only once for each translation unit. For
example, if you use register r3
without declaring it, a warning is
displayed. You can suppress the warning with --diag_suppress
.