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