2010年9月8日作成 2010年9月8日更新
MPLAB に付属している HI-TECH C for PIC10/12/16 V9.71a (PICC)でループがどんな感じにアセンブラへ展開されるかを比べてみた。
参考に、まずアセンブラで直接書いた場合
movlw 8
movwf count ; count=8
loop: bcf PORTA,RA0 ; RA0=0
decfsz count,1 ; count=count-1 して、
; 結果がゼロなら次の命令をスキップ
goto loop
5ワード!
for(count=0; count<8; count++) RA0=0;
046 1003 BCF 0x3, 0
047 3000 MOVLW 0
048 1803 BTFSC 0x3, 0
049 3001 MOVLW 0x1
04A 1283 BCF 0x3, 0x5
04B 009A MOVWF 0x1a
04C 3008 MOVLW 0x8
04D 021A SUBWF 0x1a, W
04E 1C03 BTFSS 0x3, 0
04F 2851 GOTO 0x51
050 2852 GOTO 0x52
051 2853 GOTO 0x53
052 285E GOTO 0x5e
053 1005 BCF 0x5, 0
054 3001 MOVLW 0x1
055 0097 MOVWF 0x17
056 0817 MOVF 0x17, W
057 079A ADDWF 0x1a, F
058 3008 MOVLW 0x8
059 021A SUBWF 0x1a, W
05A 1C03 BTFSS 0x3, 0
05B 285D GOTO 0x5d
05C 285E GOTO 0x5e
05D 2853 GOTO 0x53
24ワード
自分が何も考えず書くとこうなる
for(count=0; count==7; count++) RA0=0;
05E 1003 BCF 0x3, 0
05F 3000 MOVLW 0
060 1803 BTFSC 0x3, 0
061 3001 MOVLW 0x1
062 009A MOVWF 0x1a
063 081A MOVF 0x1a, W
064 3A07 XORLW 0x7
065 1903 BTFSC 0x3, 0x2
066 2868 GOTO 0x68
067 2869 GOTO 0x69
068 286A GOTO 0x6a
069 2875 GOTO 0x75
06A 1005 BCF 0x5, 0
06B 3001 MOVLW 0x1
06C 0097 MOVWF 0x17
06D 0817 MOVF 0x17, W
06E 079A ADDWF 0x1a, F
06F 081A MOVF 0x1a, W
070 3A07 XORLW 0x7
071 1903 BTFSC 0x3, 0x2
072 2874 GOTO 0x74
073 2875 GOTO 0x75
074 286A GOTO 0x6a
23ワード
for(count=8; count==0; count--) RA0=0;
075 3008 MOVLW 0x8
076 0097 MOVWF 0x17
077 0817 MOVF 0x17, W
078 009A MOVWF 0x1a
079 081A MOVF 0x1a, W
07A 1D03 BTFSS 0x3, 0x2
07B 287D GOTO 0x7d
07C 287E GOTO 0x7e
07D 2885 GOTO 0x85
07E 1005 BCF 0x5, 0
07F 3001 MOVLW 0x1
080 029A SUBWF 0x1a, F
081 081A MOVF 0x1a, W
082 1D03 BTFSS 0x3, 0x2
083 2885 GOTO 0x85
084 287E GOTO 0x7e
16ワード
「ゼロになるまで」という条件にするとだいぶ縮んだ。
count=0;
while(count<8)
{
RA0=0;
count++;
}
085 1003 BCF 0x3, 0
086 3000 MOVLW 0
087 1803 BTFSC 0x3, 0
088 3001 MOVLW 0x1
089 009A MOVWF 0x1a
08A 2890 GOTO 0x90
090 3008 MOVLW 0x8
091 021A SUBWF 0x1a, W
092 1C03 BTFSS 0x3, 0
093 2895 GOTO 0x95
094 2896 GOTO 0x96
095 288B GOTO 0x8b
08B 1005 BCF 0x5, 0
08C 3001 MOVLW 0x1
08D 0097 MOVWF 0x17
08E 0817 MOVF 0x17, W
08F 079A ADDWF 0x1a, F
17ワード
for 文の代わりに、while 文を使ったほうがコンパクトになるみたい。
count=8;
while(1)
{
RA0=0;
if(--count==0)break;
}
096 3007 MOVLW 0x8
097 0097 MOVWF 0x17
098 0817 MOVF 0x17, W
099 009A MOVWF 0x1a
0A2 289A GOTO 0x9a
09A 1005 BCF 0x5, 0
09B 3001 MOVLW 0x1
09C 029A SUBWF 0x1a, F
09D 1D03 BTFSS 0x3, 0x2
09E 28A0 GOTO 0xa0
09F 28A1 GOTO 0xa1
0A0 28A2 GOTO 0xa2
0A1 28A3 GOTO 0xa3
13ワード
Cで書いた場合、これが一番サイズが小さくなる感じ
PIC には decfsz
のように、レジスタをデクリメントして結果がゼロかどうかを調べる命令があるんだけれども、コンパイラはそれを使ってくれないみたい。
('A`)