侯濟(jì)恭
(南威軟件股份有限公司,泉州 362000)
Keil C51的開關(guān)語句目標(biāo)代碼分析*
侯濟(jì)恭
(南威軟件股份有限公司,泉州 362000)
分析目前流行的Keil C51對(duì)switch的編譯方法及其編譯效果。一般情況下,對(duì)于分支少于8的switch-case語句,目標(biāo)代碼為3層結(jié)構(gòu),即頭碼、轉(zhuǎn)移控制碼和開關(guān)體;對(duì)分支超過8個(gè)的較為復(fù)雜的switch-case,其目標(biāo)代碼分成4層,即頭碼、轉(zhuǎn)移控制碼、轉(zhuǎn)移表和開關(guān)體。考慮到代碼的執(zhí)行效率,對(duì)應(yīng)于選擇因子的數(shù)據(jù)類型,轉(zhuǎn)移控制碼調(diào)用不同的系統(tǒng)庫函數(shù)進(jìn)行處理。
嵌入式系統(tǒng);C51語言;匯編程序;編譯器
對(duì)于嵌入式系統(tǒng)的單片機(jī)程序設(shè)計(jì),其目標(biāo)代碼的運(yùn)行效率是很令人關(guān)注的[1-2]。開關(guān)語句switch是C51程序設(shè)計(jì)中的一個(gè)重要語句,其邏輯清晰、層次結(jié)構(gòu)分明、易讀性和可維護(hù)性都很好,因此受到程序設(shè)計(jì)者的青睞。本文分析目前流行的Keil C51編譯,分析其對(duì)switch的編譯方法及其編譯效果。
Keil C51編譯switch-case語句,對(duì)于分支少于8的switch-case語句,其轉(zhuǎn)移控制程序一般情況是將候選值(即case之常量)逐一比較,即編譯成比較跳轉(zhuǎn)指令形式,代碼率很高;但對(duì)分支超過8個(gè)的較為復(fù)雜的switch-case語句,考慮到代碼的執(zhí)行效率,其轉(zhuǎn)移控制程序要調(diào)用不同的系統(tǒng)庫函數(shù)進(jìn)行處理,其運(yùn)行效率差強(qiáng)人意。
分支大于8的情形,如果其Δx(即case值之間的差)小于255,則采用復(fù)雜式編譯。因?yàn)?1單片機(jī)是8位單片機(jī),執(zhí)行字符型運(yùn)算只要一條指令,執(zhí)行整型運(yùn)算至少要兩條指令,長型運(yùn)算則要4條指令?;诖a的執(zhí)行效率考量,Keil編譯對(duì)于選擇因子是字符型(8位)、整型(16位)或長型(32位),所提供的編譯略有不同,對(duì)應(yīng)的函數(shù)庫分別是CCASE、ICCASE或LCASE。編譯的目標(biāo)代碼雖然不同,但算法基本相同。
本編譯方式所產(chǎn)生的開關(guān)語句switch結(jié)構(gòu)分4層:開關(guān)頭碼、轉(zhuǎn)移控制代碼、轉(zhuǎn)移表、開關(guān)體,其結(jié)構(gòu)如圖1所示。轉(zhuǎn)移表由地址域和值域構(gòu)成,按照case值上升排序,其結(jié)構(gòu)如表1所列。
圖1 開關(guān)語句編譯后代碼結(jié)構(gòu)
表1 開關(guān)語句轉(zhuǎn)移表
控制轉(zhuǎn)移算法描述如下:
①掃描開關(guān)轉(zhuǎn)移表;
②判斷地址域是否為0;
③不為0,則跳轉(zhuǎn)至⑤;
④表終止標(biāo)志,計(jì)算switch出口地址在表中位置,跳轉(zhuǎn)至⑥;
⑤ 判斷值域是否與A相等,若不等,則跳轉(zhuǎn)至①;
⑥ 從表中取出相應(yīng)的入口,間址轉(zhuǎn)移至分支處理程序。詳細(xì)算法,參見圖2。
圖2 轉(zhuǎn)移控制算法流程
下面選擇字符型為例,說明復(fù)雜式switch編譯的目標(biāo)代碼及其代碼結(jié)構(gòu)。
例:復(fù)雜式switch源程序段如下:
編譯后的目標(biāo)代碼分解如下:
(1)轉(zhuǎn)移控制庫函數(shù)CCASE
(2)switch的開關(guān)頭碼
(3)轉(zhuǎn)移表
(4)開關(guān)體
開關(guān)體代碼物理排序沒有變化。
(5)本層的出口地址
對(duì)于分支不大于8的情形,且Δx小于255,則采用簡單形式編譯轉(zhuǎn)移控制代碼。方法如下:
設(shè)xn為n個(gè)case值,且xn>xn-1,則有
簡式的算法是:將選擇因子逐一與Δx相減,若結(jié)果為0,則轉(zhuǎn)移到相應(yīng)的分支處理程序。
例:簡式switch源程序如下:
表2為case值的編排結(jié)果,相應(yīng)的Δx如表3所列。
表2 示例中case常量排序
表3 示例中case常量的Δx
程序中減法采用補(bǔ)碼加法運(yùn)算,最后一項(xiàng)為第一個(gè)值域的值差。
(1)開關(guān)轉(zhuǎn)移控制代碼
(2)開關(guān)體
考慮到嵌入式軟件運(yùn)行效率要高的特點(diǎn),Keil對(duì)switch的編譯,根據(jù)選擇因子的數(shù)據(jù)類型,采用4種方式。其中,簡式編譯效率最高,其設(shè)計(jì)方式比較精巧,很值得程序員學(xué)習(xí)[7,8]。但在簡式switch程序中,程序員對(duì)case值的排列是毫無用處的,因此,當(dāng)根據(jù)事件發(fā)生頻度來設(shè)計(jì)程序時(shí),最好采用if語句。對(duì)于復(fù)雜式的編譯,其代碼結(jié)構(gòu)很符合程序設(shè)計(jì)的風(fēng)格,即代碼與數(shù)據(jù)分離,建立一個(gè)由地址域和值域構(gòu)成的轉(zhuǎn)移表,然后根據(jù)選擇因子的數(shù)據(jù)類型,構(gòu)造算法相同的掃描轉(zhuǎn)移表完成代碼的編譯,算法簡潔,但由于是順序掃描,效率較差[3]。對(duì)于長型的選擇因子,其編譯后的代碼較長,效率比較低,因此,
13
Analysis of Keil C51 Switch Sentence Object Code
Hou Jigong
(Linewell Software Company Limited,Quanzhou 362000,China)
Keil C51is currently the most popular embedded programming language,this paper analyzes the compiling method and effect of its"switch"sentence.In general,the branches number of the"switch-case"sentence is less than 8,the object codes are divided into three layers,that are the head code,the transfer control code and the switch body.When the branches number of the more complex"switchcase"sentence is more than 8,the target codes are divided into four layers,which are the head code,the transfer control code,the transfer sheet and the switch body.Considering the code execution efficiency,the transfer control code of the system library function is different corresponding to different data types of the selected factor.
embedded system;C51language;assembler;compiler
TP393
A
2013年福建省科技重大專項(xiàng)專題項(xiàng)目2013HZ0004-1。