Next: Local Register Variables, Up: Explicit Register Variables [Contents][Index]
You can define a global register variable and associate it with a specified register like this:
register int *foo asm ("r12");
Here r12
is the name of the register that should be used. Note that
this is the same syntax used for defining local register variables, but for
a global variable the declaration appears outside a function. The
register
keyword is required, and cannot be combined with
static
. The register name must be a valid register name for the
target platform.
Do not use type qualifiers such as const
and volatile
, as
the outcome may be contrary to expectations. In particular, using the
volatile
qualifier does not fully prevent the compiler from
optimizing accesses to the register.
Registers are a scarce resource on most systems and allowing the compiler to manage their usage usually results in the best code. However, under special circumstances it can make sense to reserve some globally. For example this may be useful in programs such as programming language interpreters that have a couple of global variables that are accessed very often.
After defining a global register variable, for the current compilation unit:
Note that these points only apply to code that is compiled with the definition. The behavior of code that is merely linked in (for example code from libraries) is not affected.
If you want to recompile source files that do not actually use your global register variable so they do not use the specified register for any other purpose, you need not actually add the global register declaration to their source code. It suffices to specify the compiler option -ffixed-reg (see Code Gen Options) to reserve the register.
Global register variables cannot have initial values, because an executable file has no means to supply initial contents for a register.
When selecting a register, choose one that is normally saved and restored by function calls on your machine. This ensures that code which is unaware of this reservation (such as library routines) will restore it before returning.
On machines with register windows, be sure to choose a global register that is not affected magically by the function call mechanism.
When calling routines that are not aware of the reservation, be
cautious if those routines call back into code which uses them. As an
example, if you call the system library version of qsort
, it may
clobber your registers during execution, but (if you have selected
appropriate registers) it will restore them before returning. However
it will not restore them before calling qsort
’s comparison
function. As a result, global values will not reliably be available to
the comparison function unless the qsort
function itself is rebuilt.
Similarly, it is not safe to access the global register variables from signal handlers or from more than one thread of control. Unless you recompile them specially for the task at hand, the system library routines may temporarily use the register for other things. Furthermore, since the register is not reserved exclusively for the variable, accessing it from handlers of asynchronous signals may observe unrelated temporary values residing in the register.
On most machines, longjmp
restores to each global register
variable the value it had at the time of the setjmp
. On some
machines, however, longjmp
does not change the value of global
register variables. To be portable, the function that called setjmp
should make other arrangements to save the values of the global register
variables, and to restore them in a longjmp
. This way, the same
thing happens regardless of what longjmp
does.
Next: Local Register Variables, Up: Explicit Register Variables [Contents][Index]