Assembly 避免使用條件分支

2018-10-28 10:08 更新

現(xiàn)代處理器使用了非常尖端的技術(shù)來盡可能快地執(zhí)行代碼。一個普遍技術(shù)稱為預(yù)測執(zhí)行。這種技術(shù)使用CPU的并行處理能力來同時執(zhí)行多條指令。條件分支與這項技術(shù)有沖突。一般說來,處理器是不知道分支是否會執(zhí)行。如果執(zhí)行了,跟沒有執(zhí)行相比執(zhí)行的是一組不同的指令。處理器試著預(yù)測分支是否執(zhí)行。如果預(yù)測錯誤,處理器就浪費了它的時間去執(zhí)行了一些錯誤的代碼。


用ADC計算位數(shù)


一個避免這個問題的辦法就是如果可能盡量避免使用條件分支。在以前的例子中,EAX寄存器中的值為\on"的位被計算出來。它使用了一個分支跳轉(zhuǎn)到INC指令。圖3.3展示了如何使用ADC指令直接加上進位標志位來替代這
個分支。


SETxx 指令提供了在一定情況下替換分支的方法?;贔LAGS寄存器的狀態(tài),這些指令將一個字節(jié)的寄存器或內(nèi)存空間中的值置為0或1。在SET后的字符與條件分支使用的是一樣的。如果SETxx 條件為真,那么儲存的結(jié)果就為1,如果為假,則儲存的結(jié)果就為0。例如:


setz      al             ; AL = 如果ZF標志位置位了則為1,否則為0。


使用這些指令,你可以開發(fā)出一些進行數(shù)值運算的精巧的技術(shù),而不需要使用分支。


例如,考慮查找兩個數(shù)的最大數(shù)的問題。這個問題的標準解決方法是使用一條CMP指令再使用條件分支對最大值進行操作。下面這個例子展示了不使用分支如何找到最大值。


實例1

實例2


這個訣竅是產(chǎn)生一個可以用來選擇出正確的最大值的俺碼。在30行的SETG指令如果第二個輸入值是最大值就將BL置為1,否則就置為0。這
不是真正需要的掩碼。為了得到真正需要的掩碼,31行對整個EBX寄存器使用了NEG指令。(注意:EBX在前面已經(jīng)置為0了。)如果EBX等于0,那
么這條指令就不做任何事情;但是如果EBX為1,結(jié)果就是-1的補碼表示或0xFFFFFFFF。這正好是需要的位掩碼。剩下的代碼就是使用這個位掩
碼來選擇出正確的輸入的最大值。


另外一個可供選擇的訣竅是使用DEC語句。在上面的代碼中,如果用DEC代替NEG,那么結(jié)果同樣會是0或0xFFFFFFFF。但是,與使用NEG相比,得到值將是反過來的。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號