29.10.2014 Views

ARM Compiler toolchain v4.1 for µVision Using the Compiler

ARM Compiler toolchain v4.1 for µVision Using the Compiler

ARM Compiler toolchain v4.1 for µVision Using the Compiler

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Using</strong> <strong>the</strong> Inline and Embedded Assemblers of <strong>the</strong> <strong>ARM</strong> <strong>Compiler</strong><br />

7.14 Inline assembler and register access in C and C++ code<br />

The inline assembler provides no direct access to <strong>the</strong> physical registers of an <strong>ARM</strong> processor.<br />

If an <strong>ARM</strong> register name is used as an operand in an inline assembler instruction it becomes a<br />

reference to a variable of <strong>the</strong> same name, and not <strong>the</strong> physical <strong>ARM</strong> register. (The variable can<br />

be thought of as a virtual register.)<br />

The compiler declares variables <strong>for</strong> physical registers as appropriate during optimization and<br />

code generation. However, <strong>the</strong> physical register used in <strong>the</strong> assembled code might be different<br />

to that specified in <strong>the</strong> instruction, or it might be stored on <strong>the</strong> stack. You can explicitly declare<br />

variables representing physical registers as normal C or C++ variables. The compiler implicitly<br />

declares registers R0 to R12 and r0 to r12 as auto signed int local variables, regardless of<br />

whe<strong>the</strong>r or not <strong>the</strong>y are used. If you want to declare <strong>the</strong>m to be of a different data type, you can<br />

do so. For example, in <strong>the</strong> following code, <strong>the</strong> compiler does not implicitly declare r1 and r2 as<br />

auto signed int because <strong>the</strong>y are explicitly declared as char and float types respectively:<br />

void bar(float *);<br />

int add(int x)<br />

{<br />

int a = 0;<br />

char r1 = 0;<br />

float r2 = 0.0;<br />

}<br />

bar(&r2);<br />

__asm<br />

{<br />

ADD r1, a, #100<br />

}<br />

...<br />

return r1;<br />

The compiler does not implicitly declare variables <strong>for</strong> any o<strong>the</strong>r registers, so you must explicitly<br />

declare variables <strong>for</strong> registers o<strong>the</strong>r than R0 to R12 and r0 to r12 in your C or C++ code. No<br />

variables are declared <strong>for</strong> <strong>the</strong> sp (r13), lr (r14), and pc (r15) registers, and <strong>the</strong>y cannot be read<br />

or directly modified in inline assembly code.<br />

There is no virtual Processor Status Register (PSR). Any references to <strong>the</strong> PSR are always to <strong>the</strong><br />

physical PSR.<br />

The size of <strong>the</strong> variables is <strong>the</strong> same as <strong>the</strong> physical registers.<br />

The compiler-declared variables have function local scope, that is, within a single function,<br />

multiple asm statements or declarations that reference <strong>the</strong> same variable name access <strong>the</strong> same<br />

virtual register.<br />

Existing inline assembler code that con<strong>for</strong>ms to previously documented guidelines continues to<br />

per<strong>for</strong>m <strong>the</strong> same function as in previous versions of <strong>the</strong> compiler, although <strong>the</strong> actual registers<br />

used in each instruction might be different.<br />

The initial value in each variable representing a physical register is unpredictable. You must<br />

write to <strong>the</strong>se variables be<strong>for</strong>e reading <strong>the</strong>m. The compiler generates an error if you attempt to<br />

read such a variable be<strong>for</strong>e writing to it, <strong>for</strong> example, if you attempt to read <strong>the</strong> variable<br />

associated with <strong>the</strong> physical register r1.<br />

Any variables that you use in inline assembler to refer to registers must be explicitly declared<br />

in your C or C++ code, unless <strong>the</strong>y are implicitly declared by <strong>the</strong> compiler. However, it is better<br />

to explicitly declare <strong>the</strong>m in your C or C++ code. You do not have to declare <strong>the</strong>m to be of <strong>the</strong><br />

<strong>ARM</strong> DUI 0375C Copyright © 2007-2008, 2011 <strong>ARM</strong>. All rights reserved. 7-18<br />

ID061811<br />

Non-Confidential

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!