高效的C编程之:寄存器分配
14.7寄存器分配
编译器一项很重要的优化功能就是对寄存器的分配。与分配在寄存器中的变量相比,分配到内存的变量访问要慢得多。所以如何将尽可能多的变量分配到寄存器,是编程时应该重点考虑的问题。
注意 |
当使用-g或-dubug选项编译程序时,为了确保调试信息的完整性,寄存器分配的效率比不使用-g或-dubug选项低很多。 |
14.7.1变量寄存器分配
一般情况下,编译器会对C函数中的每一个局部变量分配一个寄存器。如果多个局部变量不会交迭使用,那么编译器会对它们分配同一个寄存器。当局部变量多于可用的寄存器时,编译器会把多余的变量存储到堆栈。这些被写入堆栈需要访问存储器的变量被称为溢出(Spilled)变量。
为了提高程序的执行效率:
·使溢出变量的数量最少;
·确保最重要的和经常用到的变量被分配在寄存器中。
可以被分配到寄存器的变量包括:
·程序中的局部变量;
·调用子程序时传递的参数;
·与地址无关变量。
另外,在一些特定条件下,结构体中的域也可以被分配到寄存器中。
表14.1显示了当C编译器采用ARM-Thumb过程调用标准时,内部寄存器的编号、名字和分配方法。
表14.1 C编译器寄存器用法
寄存器编号 |
可选寄存器名 |
特殊寄存器名 |
寄存器用法 |
r0 |
a1 |
函数调用时的参数寄存器,用来存放前4个函数参数和存放返回值。在函数内如果将这些寄存器用作其他用途,将破坏其值。 |
|
r1 |
a2 |
||
r2 |
a3 |
||
r3 |
a4 |
||
r4 |
v1 |
通用变量寄存器 |
|
r5 |
v2 |
||
r6 |
v3 |
||
r7 |
v4 |
||
r8 |
v5 |
||
r9 |
v6或SB或TR |
平台寄存器,不同的平台对该寄存器的定义不同 |
|
r10 |
v7 |
通用变量寄存器。在使用堆栈边界检测的情况下,r10保存堆栈边界的地址 |
|
r11 |
v8 |
通用变量寄存器。 |
|
r12 |
IP |
临时过渡寄存器,函数调用时会破坏其中的值 |
|
r13 |
SP |
堆栈指针 |
|
r14 |
LR |
链接寄存器 |
|
r15 |
PC |
程序计数器 |
从表14.1可以看出,编译器可以分配14个变量到寄存器而不会发生溢出。但有些寄存器编译器会有特殊用途(如r12),所以在编写程序时应尽量限制变量的数目,使函数内部最多使用12个寄存器。
注意 |
在C语言中,可以使用关键词register给指定变量分配专用寄存器。但不同的编译器对该关键词的处理可能不同,使用时要查阅相关手册。 |
评论