目前單片機的市場競爭很激烈,許多應用出于性價比的考慮,選擇使用程序存儲空間較小(如1K,2K)的小資源8位MCU芯片進行開發。一般情況下,這類MCU沒有硬件乘法、除法指令,在程序必須使用乘除法運算時,如果單純依靠編譯器調用內部函數庫來實現,常常會有代碼量偏大、執行效率偏低的缺點。
上海晟矽微電子推出的MC30、MC32系列MCU,采用了RISC架構,在小資源8位MCU領域有廣大的用戶群和廣泛的應用,本文就以晟矽微電的這兩個系列產品的指令集為例,結合匯編與C編譯平臺,給大家介紹一種即省時又節約資源的乘除法算法。
乘法篇
單片機中的乘法是二進制的乘法,也就是把乘數的各個位與被乘數相乘,然后再相加得出,因為乘數和被乘數都是二進制,所以實際編程時每一步的乘法可以用移位實現。
例如:乘數R3=01101101,被乘數R4=11000101,乘積R1R0。步驟如下
1、清空乘積R1R0;
2、乘數的第0位是1,那被乘數R4需要乘上二進制數1,也就是左移0位,加到R1R0里;
3、乘數的第1位是0,忽略;
4、乘數的第2位是1,那被乘數R4需要乘上二進制數100,也就是左移2位,加到R1R0里;
5、乘數的第3位是1,那被乘數R4需要乘上二進制數1000,也就是左移3位,加到R1R0里;
6、乘數的第4位是0,忽略;
7、乘數的第5位是1,那被乘數R4需要乘上二進制數100000,也就是左移5位,加到R1R0里;
8、乘數的第6位是1,那被乘數R4需要乘上二進制數1000000,也就是左移6位,加到R1R0里;
9、乘數的第7位是0,忽略;
10、這時候R1R0里的值就是最后的乘積,至此算法完成。
以上例子運算結果:
R1R0 = R3 * R4= (R4<<6)+(R4<<5)+(R4<<3)+(R4<<2)+R4 = 101001111100001
實際運算流程圖見圖1.1。
圖1.1 匯編乘法運算流程圖
在實際的程序設計過程中,程序優化有兩個目標,提高程序運行效率,和減少代碼量。我們來看下本文提供的匯編算法和普通C語言編程的效率和代碼量對比。
表1.1是程序運行效率的對比數據(可能會有小的偏差),很明顯匯編編譯出來的運行時間要比C語言減少很多。
匯編(時鐘周期) | C語言(時鐘周期) | |
8*8位乘法 | 79-87 | 184-190 |
16*8位乘法 | 201-210 | 362-388 |
16*16位乘法 | 234-379 | 396-468 |
表1.1 乘法運算時鐘周期對比表
表1.2是程序代碼量的對比數據(可能會有小的偏差),匯編占用的程序空間也要比C語言小很多。
匯編(Byte) | C語言(Byte) | |
8*8位乘法 | 15 | 34 |
16*8位乘法 | 19 | 96 |
16*16位乘法 | 31 | 96 |
表1.2 乘法運算ROM空間使用情況對比表
綜上兩點,本文介紹的乘法算法各方面使用情況都要比C編譯好很多。如果大家在使用過程中,原有的程序不能滿足應用需求,例如遇到程序空間不夠或者運行時間太久等問題,都可以按照以上方式進行優化。匯編語言最接近機器語言的。在匯編語言中可以直接操作寄存器,調整指令執行順序。由于匯編語言直接面對硬件平臺,而不同的硬件平臺的指令集及指令周期均有較大差異,這樣會對程序的移植和維護造成一定的不便,所以我們針對精簡指令集做了乘法運算的例程,便于大家的移植和理解。
除法篇
單片機中的除法也是二進制的除法,和現實中數學的除法類似,是從被除數的高位開始,按位對除數進行相處取余的運算,得出的余數再和之后的被除數一起再進行新的相除取余的運算,直到除不盡為止,因為單片機中的除法是二進制的,每個步驟除出來的商最大只有1,所以我們實際編程時可以把每一步的除法看作減法運算。
例如:被除數R3R4=1100110001101101,除數R5=11000101,商R1R0,余數R2。步驟如下
1、清空商R1R0,余數R2;
2、被除數放開最高位,第15位,為1,1比除數小,商為0,余數R2為1;
3、上一步余數并上被除數次高位,第14位,得11,11仍然比除數小,商為0,余數R2為11
4、直到放開第8位后,得11001100,比除數大,商得1,余數R2為111;
5、上一步余數并上被除數第7位,得1110,沒有除數大,商為0,余數R2為1110;
6、上一步余數并上被除數第6位,得11101,沒有除數大,商為0,余數R2為11101;
7、按照以上步驟,直到放開了被除數得第3位,得11101101,比除數大,商為1,余數R2為101000;
8、上一步余數并上被除數第2位,得1010001,沒有除數大,商為0,余數R2為1010001;
9、上一步余數并上被除數第1位,得10100010,沒有除數大,商為0,余數R2為10100010;
10、上一步余數并上被除數第0位,得101000101,比除數大,商為1,余數R2為10000000;
11、然后把以上所有步驟中得商從左至右依次排列就是最后的商100001001,余數為最后算得的余數10000000。
以上例子運算結果 R1R0 = R3R4 / R5 = 100001001
R2 = R3R4 % R5 = 10000000
實際運算流程圖見圖2.1。
圖2.1 匯編除法運算流程圖
除法運算的效率,代碼量見以下表格
表1.1是程序運行效率和代碼量的對比數據(可能會有小的偏差),很明顯本文提供的匯編算法要優化的很多。
16/8位除法 | 匯編 | C語言 |
時鐘周期 | 287-321 | 740-804 |
使用空間(Byte) | 35 | 142 |
表2.1 除法運算時鐘周期對比表
所以對于除法運算,本文提供的方法也是相對較優的。
以下是針對精簡指令集做的除法運算,16/8位的例程,便于大家的移植和理解。
-
單片機
+關注
關注
6050文章
44701瀏覽量
641287 -
mcu
+關注
關注
146文章
17473瀏覽量
354596 -
編程
+關注
關注
88文章
3649瀏覽量
94355
原文標題:針對小容量單片機程序優化方式--乘除法篇
文章出處:【微信號:eet-china,微信公眾號:電子工程專輯】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
乘除法運算
霧盈FPGA筆記之(三十二)六位四則運算計算器(8)算法實現加減乘除
整數乘除法與位運算的效率對比分析哪個好
乘除法和開方運算的FPGA串行實現
單片機浮點數的快速除法

一種模擬除法器的設計及仿真驗證CMOS工藝
基于delta碼的乘除法運算錯誤檢測改進算法
基于StratixⅡEP2S30484C5芯片的乘除法和開方運算算法的實現

一種節約內存的增量更新算法

評論