Retired Documents Library Developer
Search

Previous: Global Reg Vars, Up: Explicit Reg Vars


5.40.2 Specifying Registers for Local Variables

You can define a local register variable with a specified register like this:

     register int *foo asm ("a5");

Here a5 is the name of the register which should be used. Note that this is the same syntax used for defining global register variables, but for a local variable it would appear within a function.

Naturally the register name is cpu-dependent, but this is not a problem, since specific registers are most often useful with explicit assembler instructions (see Extended Asm). Both of these things generally require that you conditionalize your program according to cpu type.

In addition, operating systems on one type of cpu may differ in how they name the registers; then you would need additional conditionals. For example, some 68000 operating systems call this register %a5.

Defining such a register variable does not reserve the register; it remains available for other uses in places where flow control determines the variable's value is not live.

This option does not guarantee that GCC will generate code that has this variable in the register you specify at all times. You may not code an explicit reference to this register in the assembler instruction template part of an asm statement and assume it will always refer to this variable. However, using the variable as an asm operand guarantees that the specified register is used for the operand.

Stores into local register variables may be deleted when they appear to be dead according to dataflow analysis. References to local register variables may be deleted or moved or simplified.

As for global register variables, it's recommended that you choose a register which is normally saved and restored by function calls on your machine, so that library routines will not clobber it. A common pitfall is to initialize multiple call-clobbered registers with arbitrary expressions, where a function call or library call for an arithmetic operator will overwrite a register value from a previous assignment, for example r0 below:

     register int *p1 asm ("r0") = ...;
     register int *p2 asm ("r1") = ...;

In those cases, a solution is to use a temporary variable for each arbitrary expression. See Example of asm with clobbered asm reg.