加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 14.4  布爾表達(dá)式
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

高效的C編程之:布爾表達(dá)式

2013/09/30
閱讀需 8 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

 

14.4  布爾表達(dá)式

14.4.1  范圍檢測

通常,布爾表達(dá)式被用來檢測某個(gè)數(shù)值是否在特定的范圍內(nèi)。例如,在圖形窗口處理程序中,常使用布爾表達(dá)式判斷屏幕中一個(gè)點(diǎn)是否在當(dāng)前活動(dòng)窗口范圍內(nèi)。

下面的程序使用結(jié)構(gòu)體定義點(diǎn)坐標(biāo)并計(jì)算坐標(biāo)的當(dāng)前位置。

bool PointInRect1(Point p, Rectangle *r)

{  return (p.x >= r->xmin && p.x < r->xmax &&

                p.y >= r->ymin && p.y < r->ymax);

}

上面的功能函數(shù),被編譯為下面的指令序列。

PointInRect1

           LDR      a4,[a3,#0]

           CMP      a1,a4

           BLT      |L000034.J5.PointInRect1|

           LDR      a4,[a3,#4]

           CMP      a4,a1

           BLE      |L000034.J5.PointInRect1|

           LDR      a1,[a3,#8]

           CMP      a2,a1

           BLT      |L000034.J5.PointInRect1|

           LDR      a1,[a3,#&c]!

           CMP      a2,a1

           MOVLT    a1,#1

           MOVLT    pc,lr

|L000034.J5.PointInRect1|

           MOV      a1,#0

           MOV      pc,lr

但上面的代碼并不是最精簡的。編譯器對(x >= min && x < max)形式的布爾表達(dá)式的處理過程比較復(fù)雜。它將以(unsigned)(x-min) < (max-min)形式實(shí)現(xiàn)布爾操作。所有對于上面范圍判斷的代碼,建議將函數(shù)寫成如下形式。

bool PointInRect2(Point p, Rectangle *r)

{  return ((unsigned) (p.x - r->xmin) < r->xmax &&

               (unsigned) (p.y - r->ymin) < r->ymax);

}

這樣編譯出的匯編指令序列如下所示。

PointInRect2

           LDR      a4,[a3,#0]

           SUB      a1,a1,a4

           LDR      a4,[a3,#4]

           CMP      a1,a4

           LDRCC    a1,[a3,#8]

           SUBCC    a1,a2,a1

           LDRCC    a2,[a3,#&c]!

           CMPCC    a1,a2

           MOVCS    a1,#0

           MOVCC    a1,#1

           MOV      pc,lr

14.4.2  和零的比較操作

比較指令(CMP)將設(shè)置程序狀態(tài)字的條件標(biāo)志位。另外,基本的算術(shù)指令也可以設(shè)置條件標(biāo)志位,如使用指令MOVS、ADDS等。如果程序中的算術(shù)指令的執(zhí)行目的是為了將計(jì)算結(jié)果和零比較,那么就可以直接使用帶標(biāo)志擴(kuò)展的基本算術(shù)指令。如下面的兩條語句:

ADD R0, R0, R1

CMP R0, #0

可以合并為一條帶符號擴(kuò)展的加法指令:

ADDS R0, R0, R1

事實(shí)上,C語言中的和零相關(guān)的關(guān)系操作都可以利用狀態(tài)標(biāo)志寄存器的N位和Z位。如:x < 0, x >= 0, x = 0, x != 0,和無符號操作x = 0, x != 0 (or x > 0)。

對于每一條C語言中的關(guān)系操作,匯編器都將產(chǎn)生一條比較指令。如果關(guān)系操作和零相關(guān),則可以將產(chǎn)生的比較指令移除。

 

下面是C語言中的關(guān)系操作被編譯的例子。

C源文件如下所示。

int g(int x, int y)

{

if ((x + y) < 0)

return 1;

else

return 0;

}

編譯后的結(jié)果如下。

g

        ADDS     a1,a1,a2

        MOVPL    a1,#0

        MOVMI    a1,#1

        MOV      pc,lr

所以,在使用C語言編程時(shí),關(guān)系操作最好轉(zhuǎn)換成和零相關(guān)的,這樣既可以減少代碼密度,也可以提高程序的執(zhí)行效率。

C語言中,沒有和程序狀態(tài)寄存器的C位和V位直接相關(guān)的指令,所以要在程序中檢測這些標(biāo)志,只能使用內(nèi)嵌匯編。但C編譯器支持無符號溢出操作,下面的例子顯示了在有溢出操作時(shí),編譯器對程序的處理。

C源代碼如下所示。

int sum(int x, int y)

{

int res;

res = x + y;

if ((unsigned) res < (unsigned) x) /* 判斷進(jìn)位標(biāo)志是否進(jìn)位 */

res++;

return res;

}

編譯的匯編文件如下所示。

sum

        ADDS     a2,a1,a2

        ADC      a2,a2,#0

        MOV      a1,a2

        MOV      pc,lr

Arm

Arm

ARM公司是一家知識產(chǎn)權(quán)(IP)供應(yīng)商,主要為國際上其他的電子公司提供高性能RISC處理器、外設(shè)和系統(tǒng)芯片技術(shù)授權(quán)。目前,ARM公司的處理器內(nèi)核已經(jīng)成為便攜通訊、手持計(jì)算設(shè)備、多媒體數(shù)字消費(fèi)品等方案的RISC標(biāo)準(zhǔn)。公司1990年11月由Acorn、Apple和VLSI合并而成。

ARM公司是一家知識產(chǎn)權(quán)(IP)供應(yīng)商,主要為國際上其他的電子公司提供高性能RISC處理器、外設(shè)和系統(tǒng)芯片技術(shù)授權(quán)。目前,ARM公司的處理器內(nèi)核已經(jīng)成為便攜通訊、手持計(jì)算設(shè)備、多媒體數(shù)字消費(fèi)品等方案的RISC標(biāo)準(zhǔn)。公司1990年11月由Acorn、Apple和VLSI合并而成。收起

查看更多

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

華清遠(yuǎn)見(www.farsight.com.cn)是國內(nèi)領(lǐng)先嵌入師培訓(xùn)機(jī)構(gòu),2004年注冊于中國北京海淀高科技園區(qū),除北京總部外,上海、深圳、成都、南京、武漢、西安、廣州均有直營分公司。華清遠(yuǎn)見除提供嵌入式相關(guān)的長期就業(yè)培訓(xùn)、短期高端培訓(xùn)、師資培訓(xùn)及企業(yè)員工內(nèi)訓(xùn)等業(yè)務(wù)外,其下屬研發(fā)中心還負(fù)責(zé)嵌入式、Android及物聯(lián)網(wǎng)方向的教學(xué)實(shí)驗(yàn)平臺的研發(fā)及培訓(xùn)教材的出版,截止目前為止已公開出版70余本嵌入式/移動(dòng)開發(fā)/物聯(lián)網(wǎng)相關(guān)圖書。企業(yè)理念:專業(yè)始于專注 卓識源于遠(yuǎn)見。企業(yè)價(jià)值觀:做良心教育、做專業(yè)教育,更要做受人尊敬的職業(yè)教育。