|
目前單片機的市場競爭很激烈,許多應(yīng)用出于性價比的考慮,選擇使用程序存儲空間較?。ㄈ?K,2K)的小資源8位MCU芯片進行開發(fā)。一般情況下,這類MCU沒有硬件乘法、除法指令,在程序必須使用乘除法運算時,如果單純依靠編譯器調(diào)用內(nèi)部函數(shù)庫來實現(xiàn),常常會有代碼量偏大、執(zhí)行效率偏低的缺點。 上海晟矽微電子推出的MC30、MC32系列MCU,采用了RISC架構(gòu),在小資源8位MCU領(lǐng)域有廣大的用戶群和廣泛的應(yīng)用,本文就以晟矽微電的這兩個系列產(chǎn)品的指令集為例,結(jié)合匯編與C編譯平臺,給大家介紹一種即省時又節(jié)約資源的乘除法算法。
乘法篇 單片機中的乘法是二進制的乘法,也就是把乘數(shù)的各個位與被乘數(shù)相乘,然后再相加得出,因為乘數(shù)和被乘數(shù)都是二進制,所以實際編程時每一步的乘法可以用移位實現(xiàn)。
例如:乘數(shù)R3=01101101,被乘數(shù)R4=11000101,乘積R1R0。步驟如下 1、清空乘積R1R0; 2、乘數(shù)的第0位是1,那被乘數(shù)R4需要乘上二進制數(shù)1,也就是左移0位,加到R1R0里; 3、乘數(shù)的第1位是0,忽略; 4、乘數(shù)的第2位是1,那被乘數(shù)R4需要乘上二進制數(shù)100,也就是左移2位,加到R1R0里; 5、乘數(shù)的第3位是1,那被乘數(shù)R4需要乘上二進制數(shù)1000,也就是左移3位,加到R1R0里; 6、乘數(shù)的第4位是0,忽略; 7、乘數(shù)的第5位是1,那被乘數(shù)R4需要乘上二進制數(shù)100000,也就是左移5位,加到R1R0里; 8、乘數(shù)的第6位是1,那被乘數(shù)R4需要乘上二進制數(shù)1000000,也就是左移6位,加到R1R0里; 9、乘數(shù)的第7位是0,忽略; 10、這時候R1R0里的值就是最后的乘積,至此算法完成。 以上例子運算結(jié)果: R1R0 = R3 * R4= (R4<><><><2)+r4 =="">2)+r4> 實際運算流程圖見圖1.1。 圖1.1 匯編乘法運算流程圖 在實際的程序設(shè)計過程中,程序優(yōu)化有兩個目標,提高程序運行效率,和減少代碼量。我們來看下本文提供的匯編算法和普通C語言編程的效率和代碼量對比。 表1.1是程序運行效率的對比數(shù)據(jù)(可能會有小的偏差),很明顯匯編編譯出來的運行時間要比C語言減少很多。
表1.1 乘法運算時鐘周期對比表 表1.2是程序代碼量的對比數(shù)據(jù)(可能會有小的偏差),匯編占用的程序空間也要比C語言小很多。
表1.2 乘法運算ROM空間使用情況對比表 綜上兩點,本文介紹的乘法算法各方面使用情況都要比C編譯好很多。如果大家在使用過程中,原有的程序不能滿足應(yīng)用需求,例如遇到程序空間不夠或者運行時間太久等問題,都可以按照以上方式進行優(yōu)化。 除法篇 單片機中的除法也是二進制的除法,和現(xiàn)實中數(shù)學(xué)的除法類似,是從被除數(shù)的高位開始,按位對除數(shù)進行相處取余的運算,得出的余數(shù)再和之后的被除數(shù)一起再進行新的相除取余的運算,直到除不盡為止,因為單片機中的除法是二進制的,每個步驟除出來的商最大只有1,所以我們實際編程時可以把每一步的除法看作減法運算。
例如:被除數(shù)R3R4=1100110001101101,除數(shù)R5=11000101,商R1R0,余數(shù)R2。步驟如下 1、清空商R1R0,余數(shù)R2; 2、被除數(shù)放開最高位,第15位,為1,1比除數(shù)小,商為0,余數(shù)R2為1; 3、上一步余數(shù)并上被除數(shù)次高位,第14位,得11,11仍然比除數(shù)小,商為0,余數(shù)R2為11 4、直到放開第8位后,得11001100,比除數(shù)大,商得1,余數(shù)R2為111; 5、上一步余數(shù)并上被除數(shù)第7位,得1110,沒有除數(shù)大,商為0,余數(shù)R2為1110; 6、上一步余數(shù)并上被除數(shù)第6位,得11101,沒有除數(shù)大,商為0,余數(shù)R2為11101; 7、按照以上步驟,直到放開了被除數(shù)得第3位,得11101101,比除數(shù)大,商為1,余數(shù)R2為101000; 8、上一步余數(shù)并上被除數(shù)第2位,得1010001,沒有除數(shù)大,商為0,余數(shù)R2為1010001; 9、上一步余數(shù)并上被除數(shù)第1位,得10100010,沒有除數(shù)大,商為0,余數(shù)R2為10100010; 10、上一步余數(shù)并上被除數(shù)第0位,得101000101,比除數(shù)大,商為1,余數(shù)R2為10000000; 11、然后把以上所有步驟中得商從左至右依次排列就是最后的商100001001,余數(shù)為最后算得的余數(shù)10000000。 以上例子運算結(jié)果 R1R0 = R3R4 / R5 = 100001001 R2 = R3R4 % R5 = 10000000 實際運算流程圖見圖2.1。 圖2.1 匯編除法運算流程圖
除法運算的效率,代碼量見以下表格 表1.1是程序運行效率和代碼量的對比數(shù)據(jù)(可能會有小的偏差),很明顯本文提供的匯編算法要優(yōu)化的很多。
表2.1 除法運算時鐘周期對比表 所以對于除法運算,本文提供的方法也是相對較優(yōu)的。 以下是針對精簡指令集做的除法運算,16/8位的例程,便于大家的移植和理解。 |
|
|
來自: 西北望msm66g9f > 《編程》