Keil Logo

Technical Support

On-Line Manuals

Compiler User Guide

Preface Overview of the Compiler Getting Started with the Compiler Compiler Features Compiler Coding Practices Compiler Diagnostic Messages Using the Inline and Embedded Assemblers of the AR Compiler support for inline assembly language Inline assembler support in the compiler Restrictions on inline assembler support in the co Inline assembly language syntax with the __asm key Inline assembly language syntax with the asm keywo Inline assembler rules for compiler keywords __asm Restrictions on inline assembly operations in C an Inline assembler register restrictions in C and C+ Inline assembler processor mode restrictions in C Inline assembler Thumb instruction set restriction Inline assembler Vector Floating-Point (VFP) restr Inline assembler instruction restrictions in C and Miscellaneous inline assembler restrictions in C a Inline assembler and register access in C and C++ Inline assembler and the # constant expression spe Inline assembler and instruction expansion in C an Expansion of inline assembler instructions that us Expansion of inline assembler load and store instr Inline assembler effect on processor condition fla Inline assembler expression operands in C and C++ Inline assembler register list operands in C and C Inline assembler intermediate operands in C and C+ Inline assembler function calls and branches in C Inline assembler branches and labels in C and C++ Inline assembler and virtual registers Embedded assembler support in the compiler Embedded assembler syntax in C and C++ Effect of compiler ARM and Thumb states on embedde Restrictions on embedded assembly language functio Compiler generation of embedded assembly language Access to C and C++ compile-time constant expressi Differences between expressions in embedded assemb Manual overload resolution in embedded assembler __offsetof_base keyword for related base classes i Compiler-supported keywords for calling class memb __mcall_is_virtual(D, f) __mcall_is_in_vbase(D, f) __mcall_offsetof_vbase(D, f) __mcall_this_offset(D, f) __vcall_offsetof_vfunc(D, f) Calling nonstatic member functions in embedded ass Calling a nonvirtual member function Calling a virtual member function Accessing sp (r13), lr (r14), and pc (r15) Differences in compiler support for inline and emb Compiler Command-line Options Language Extensions Compiler-specific Features C and C++ Implementation Details What is Semihosting? Via File Syntax Summary Table of GNU Language Extensions Standard C Implementation Definition Standard C++ Implementation Definition C and C++ Compiler Implementation Limits

Inline assembler and register access in C and C++ code

6.14 Inline assembler and register access in C and C++ code

The inline assembler provides no direct access to the physical registers of an ARM processor. If an ARM register name is used as an operand in an inline assembler instruction it becomes a reference to a variable of the same name, and not the physical ARM register.

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.
Non-ConfidentialPDF file icon PDF versionARM DUI0375H
Copyright © 2007, 2008, 2011, 2012, 2014-2016 ARM. All rights reserved. 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

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.