侯濟恭
(南威軟件股份有限公司,泉州 362000)
Keil C51的開關語句目標代碼分析*
侯濟恭
(南威軟件股份有限公司,泉州 362000)
分析目前流行的Keil C51對switch的編譯方法及其編譯效果。一般情況下,對于分支少于8的switch-case語句,目標代碼為3層結構,即頭碼、轉移控制碼和開關體;對分支超過8個的較為復雜的switch-case,其目標代碼分成4層,即頭碼、轉移控制碼、轉移表和開關體。考慮到代碼的執行效率,對應于選擇因子的數據類型,轉移控制碼調用不同的系統庫函數進行處理。
嵌入式系統;C51語言;匯編程序;編譯器
對于嵌入式系統的單片機程序設計,其目標代碼的運行效率是很令人關注的[1-2]。開關語句switch是C51程序設計中的一個重要語句,其邏輯清晰、層次結構分明、易讀性和可維護性都很好,因此受到程序設計者的青睞。本文分析目前流行的Keil C51編譯,分析其對switch的編譯方法及其編譯效果。
Keil C51編譯switch-case語句,對于分支少于8的switch-case語句,其轉移控制程序一般情況是將候選值(即case之常量)逐一比較,即編譯成比較跳轉指令形式,代碼率很高;但對分支超過8個的較為復雜的switch-case語句,考慮到代碼的執行效率,其轉移控制程序要調用不同的系統庫函數進行處理,其運行效率差強人意。
分支大于8的情形,如果其Δx(即case值之間的差)小于255,則采用復雜式編譯。因為51單片機是8位單片機,執行字符型運算只要一條指令,執行整型運算至少要兩條指令,長型運算則要4條指令。基于代碼的執行效率考量,Keil編譯對于選擇因子是字符型(8位)、整型(16位)或長型(32位),所提供的編譯略有不同,對應的函數庫分別是CCASE、ICCASE或LCASE。編譯的目標代碼雖然不同,但算法基本相同。
本編譯方式所產生的開關語句switch結構分4層:開關頭碼、轉移控制代碼、轉移表、開關體,其結構如圖1所示。轉移表由地址域和值域構成,按照case值上升排序,其結構如表1所列。

圖1 開關語句編譯后代碼結構

表1 開關語句轉移表
控制轉移算法描述如下:
①掃描開關轉移表;
②判斷地址域是否為0;
③不為0,則跳轉至⑤;
④表終止標志,計算switch出口地址在表中位置,跳轉至⑥;
⑤ 判斷值域是否與A相等,若不等,則跳轉至①;
⑥ 從表中取出相應的入口,間址轉移至分支處理程序。詳細算法,參見圖2。

圖2 轉移控制算法流程
下面選擇字符型為例,說明復雜式switch編譯的目標代碼及其代碼結構。
例:復雜式switch源程序段如下:

編譯后的目標代碼分解如下:
(1)轉移控制庫函數CCASE


(2)switch的開關頭碼

(3)轉移表


(4)開關體
開關體代碼物理排序沒有變化。

(5)本層的出口地址

對于分支不大于8的情形,且Δx小于255,則采用簡單形式編譯轉移控制代碼。方法如下:
設xn為n個case值,且xn>xn-1,則有

簡式的算法是:將選擇因子逐一與Δx相減,若結果為0,則轉移到相應的分支處理程序。
例:簡式switch源程序如下:

表2為case值的編排結果,相應的Δx如表3所列。

表2 示例中case常量排序

表3 示例中case常量的Δx
程序中減法采用補碼加法運算,最后一項為第一個值域的值差。
(1)開關轉移控制代碼

(2)開關體

考慮到嵌入式軟件運行效率要高的特點,Keil對switch的編譯,根據選擇因子的數據類型,采用4種方式。其中,簡式編譯效率最高,其設計方式比較精巧,很值得程序員學習[7,8]。但在簡式switch程序中,程序員對case值的排列是毫無用處的,因此,當根據事件發生頻度來設計程序時,最好采用if語句。對于復雜式的編譯,其代碼結構很符合程序設計的風格,即代碼與數據分離,建立一個由地址域和值域構成的轉移表,然后根據選擇因子的數據類型,構造算法相同的掃描轉移表完成代碼的編譯,算法簡潔,但由于是順序掃描,效率較差[3]。對于長型的選擇因子,其編譯后的代碼較長,效率比較低,因此,
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年福建省科技重大專項專題項目2013HZ0004-1。