高效的C編程之:寄存器分配
14.7寄存器分配
編譯器一項很重要的優(yōu)化功能就是對寄存器的分配。與分配在寄存器中的變量相比,分配到內(nèi)存的變量訪問要慢得多。所以如何將盡可能多的變量分配到寄存器,是編程時應(yīng)該重點考慮的問題。
注意 | 當(dāng)使用-g或-dubug選項編譯程序時,為了確保調(diào)試信息的完整性,寄存器分配的效率比不使用-g或-dubug選項低很多。 |
14.7.1變量寄存器分配
一般情況下,編譯器會對C函數(shù)中的每一個局部變量分配一個寄存器。如果多個局部變量不會交迭使用,那么編譯器會對它們分配同一個寄存器。當(dāng)局部變量多于可用的寄存器時,編譯器會把多余的變量存儲到堆棧。這些被寫入堆棧需要訪問存儲器的變量被稱為溢出(Spilled)變量。
為了提高程序的執(zhí)行效率:
·使溢出變量的數(shù)量最少;
·確保最重要的和經(jīng)常用到的變量被分配在寄存器中。
可以被分配到寄存器的變量包括:
·程序中的局部變量;
·調(diào)用子程序時傳遞的參數(shù);
·與地址無關(guān)變量。
另外,在一些特定條件下,結(jié)構(gòu)體中的域也可以被分配到寄存器中。
表14.1顯示了當(dāng)C編譯器采用ARM-Thumb過程調(diào)用標準時,內(nèi)部寄存器的編號、名字和分配方法。
表14.1 C編譯器寄存器用法
寄存器編號 | 可選寄存器名 | 特殊寄存器名 | 寄存器用法 |
r0 | a1 | 函數(shù)調(diào)用時的參數(shù)寄存器,用來存放前4個函數(shù)參數(shù)和存放返回值。在函數(shù)內(nèi)如果將這些寄存器用作其他用途,將破壞其值。 | |
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 | 臨時過渡寄存器,函數(shù)調(diào)用時會破壞其中的值 | |
r13 | SP | 堆棧指針 | |
r14 | LR | 鏈接寄存器 | |
r15 | PC | 程序計數(shù)器 |
從表14.1可以看出,編譯器可以分配14個變量到寄存器而不會發(fā)生溢出。但有些寄存器編譯器會有特殊用途(如r12),所以在編寫程序時應(yīng)盡量限制變量的數(shù)目,使函數(shù)內(nèi)部最多使用12個寄存器。
注意 | 在C語言中,可以使用關(guān)鍵詞register給指定變量分配專用寄存器。但不同的編譯器對該關(guān)鍵詞的處理可能不同,使用時要查閱相關(guān)手冊。 |
評論