C语言中定义了这么一种变量,将变量可以存储在处理器中的寄存器内,比如eax等,这样可以提高变量访问的速度,比如linux0.12内核中有这样一个函数:
static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
unsigned int head,unsigned int cyl,unsigned int cmd,
void (*intr_addr)(void))
{
register int port asm("dx"); //该定义也同时使用了GCC的C扩展语法
if (drive>1 || head>15)
panic("Trying to write bad sector");
if (!controller_ready())
panic("HD controller not ready");
SET_INTR(intr_addr);
outb_p(hd_info[drive].ctl,HD_CMD);
port=HD_DATA;
outb_p(hd_info[drive].wpcom>>2,++port);
outb_p(nsect,++port);
outb_p(sect,++port);
outb_p(cyl,++port);
outb_p(cyl>>8,++port);
outb_p(0xA0|(drive<<4)|head,++port);
outb(cmd,++port);
}
在"The C programming Language"中这样描述register变量的用法:
Register Variables
A register declaration advises the compiler that the variable in question will be heavily used. The idea is that register
variables are to be placed in machine registers, which may result in smaller and faster programs. But compilers are free to
ignore the advice.
The register declaration looks like
register int x;
register char c;
and so on. The register declaration can only be applied to automatic variables and to the formal parameters of a function. In
this later case, it looks like
f(register unsigned m, register long n)
{
register int i;
...
}
In practice, there are restrictions on register variables, reflecting the realities of underlying hardware. Only a few variables in
each function may be kept in registers, and only certain types are allowed. Excess register declarations are harmless,
however, since the word register is ignored for excess or disallowed declarations. And it is not possible to take the address
of a register variable (a topic covered in Chapter 5), regardless of whether the variable is actually placed in a register. The
specific restrictions on number and types of register variables vary from machine to machine.
"Using and Porting the GNU Compiler Collection"中定义了C语言register变量的扩展语法:
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 Section 5.36 [Extended
Asm], page 185). 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. However,
these registers are made unavailable for use in the reload pass; excessive use of this feature
leaves the compiler too few available registers to compile certain functions.
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 an asm statement and assume it will always refer to this variable.
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.