|
相关连接:参与社区讨论
--------------------------------------------------------------------
天梯 之 从零开始玩PIC——8.“*3”算法的最优写法
--------------------------------------------------------------------
今天的故事源于一个“*3”算法的实现,匠人想了解一下编译器是如何处理“* 3”的动作的,于是写了几种不同的c语言写法。交给编译器去编译,看看谁更傻?结果很有趣,如下:
371: //写法1(这种方法,需要调用乘法,没效率!) 372: S_LINE = 3 * TIME_S ; 079C 3003 MOVLW 0x3 079D 00F1 MOVWF 0x71 079E 0833 MOVF 0x33, W 079F 120A BCF 0xa, 0x4 07A0 118A BCF 0xa, 0x3 07A1 2777 CALL 0x777 (注意看这里,居然调用了乘法函数!) 07A2 00AC MOVWF 0x2c 373: 374: //写法2(与方法1等效,也需要调用乘法,没效率!) 375: S_LINE = TIME_S + TIME_S + TIME_S ; 07A3 3003 MOVLW 0x3 07A4 00F1 MOVWF 0x71 07A5 0833 MOVF 0x33, W 07A6 120A BCF 0xa, 0x4 07A7 118A BCF 0xa, 0x3 07A8 2777 CALL 0x777 (注意看这里,居然调用了乘法函数!) 07A9 00AC MOVWF 0x2c 376: 377: //写法3(也需要调用乘法,没效率!) 378: S_LINE = (TIME_S << 1) + TIME_S ; 07AA 3003 MOVLW 0x3 07AB 00F1 MOVWF 0x71 07AC 0833 MOVF 0x33, W 07AD 120A BCF 0xa, 0x4 07AE 118A BCF 0xa, 0x3 07AF 2777 CALL 0x777 (注意看这里,居然调用了乘法函数!) 07B0 120A BCF 0xa, 0x4 07B1 118A BCF 0xa, 0x3 07B2 00AC MOVWF 0x2c 379: 380: //写法4(这种写法,编译结果居然比前两种方法更精简?) 381: S_LINE = TIME_S ; 07B3 0833 MOVF 0x33, W 07B4 00AC MOVWF 0x2c 382: S_LINE = S_LINE + TIME_S ; 07B5 0833 MOVF 0x33, W 07B6 07AC ADDWF 0x2c, F 383: S_LINE = S_LINE + TIME_S ; 07B7 07AC ADDWF 0x2c, F 384: 385: //写法5(没想到吧?这样写居然最精简!) 386: S_LINE = 2 * TIME_S ; 07B8 0733 ADDWF 0x33, W 07B9 00AC MOVWF 0x2c 387: S_LINE = S_LINE + TIME_S ; 07BA 0833 MOVF 0x33, W 07BB 07AC ADDWF 0x2c, F
---------------------------------------------------------------------------------------------------
看来,在写c语言过程中,优化工作还得人工干预一下才好.
下面是另一个优化的例子:
---------------------------------------------------------------------------------------------------
----------------------------------------写法1:
382: H_LINE = TIME_H / 2 * 15 + TIME_M / 4 ; //时针定位="时"/2*15+"分"/4 078D 300F MOVLW 0xf 078E 00F1 MOVWF 0x71 078F 1003 BCF 0x3, 0 0790 0C30 RRF 0x30, W 0791 120A BCF 0xa, 0x4 0792 118A BCF 0xa, 0x3 0793 2768 CALL 0x768 (注意看这里,居然调用了乘法函数!) 0794 120A BCF 0xa, 0x4 0795 118A BCF 0xa, 0x3 0796 00F0 MOVWF 0x70 0797 0831 MOVF 0x31, W 0798 00F1 MOVWF 0x71 0799 1003 BCF 0x3, 0 079A 0CF1 RRF 0x71, F 079B 1003 BCF 0x3, 0 079C 0C71 RRF 0x71, W 079D 0770 ADDWF 0x70, W 079E 00A4 MOVWF 0x24
----------------------------------------写法2:
418: i = TIME_H / 2 ; 07A1 1003 BCF 0x3, 0 07A2 0C30 RRF 0x30, W 07A3 00C1 MOVWF 0x41 419: j = TIME_H * 8 - i ; 07A4 0830 MOVF 0x30, W 07A5 00F0 MOVWF 0x70 07A6 1003 BCF 0x3, 0 07A7 0DF0 RLF 0x70, F 07A8 1003 BCF 0x3, 0 07A9 0DF0 RLF 0x70, F 07AA 1003 BCF 0x3, 0 07AB 0D70 RLF 0x70, W 07AC 00F0 MOVWF 0x70 07AD 0841 MOVF 0x41, W 07AE 0270 SUBWF 0x70, W 07AF 00C0 MOVWF 0x40 420: i = TIME_M / 4 ; 07B0 0831 MOVF 0x31, W 07B1 00F0 MOVWF 0x70 07B2 1003 BCF 0x3, 0 07B3 0CF0 RRF 0x70, F 07B4 1003 BCF 0x3, 0 07B5 0C70 RRF 0x70, W 07B6 00C1 MOVWF 0x41 421: H_LINE = j - i ; //时针定位="时"/2*15+"分"/4 07B7 0240 SUBWF 0x40, W 07B8 00A4 MOVWF 0x24
|