忍者ブログ
ようこそ!JQ2RVNのブログです。 PICを使っていろいろな物を作ろうと画策中です。
[11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

CCS Cコンパイラを使っている時、
条件文が、アセンブラに翻訳されるかを調べてみました。
さらに、どのように書けば最適であるかも調べました。

まず、以下のような処理を考えます。

UARTで8ビットのデータを送信するとき、
8ビット分は処理Aで、ストップビットを処理Bで行う。

通常ならば、while文を使うところですが、
タイマーの割り込みを使っているなどの理由で
if文にしないといけないということにしておきましょう。

順当に書けばこんな感じでしょうか?

i++;

if( i > 8 )
    処理B
else
    処理A

しかし、この場合if( i > 8 )の計算のために
引き算をしてキャリービットを検査するなど、
かなり面倒な条件処理になります。

 


 

逆にiを減算していったほうが、処理としてはスマートになります。
初期値としてi=8を与えておいて

i--;

if( i == 0 )
    処理B
else
    処理A

こうしておくと、
decf i,f
btfsc status , z
goto else
となって、2命令で条件分岐できそうと考えます。
が、しかし、そうはなってくれません。

どうやら、i==0と比較しようとすると、
8ビット幅でチェックしようとするみたいで、
結局XOR命令を使ってしまいます。
( A XOR B = 0 ならば A = B を使う)

 


 

このあたりを考慮すると、if文内はビット演算として書かないといけないようです。
つまり、比較演算子(==とか>とか<とか)を使わずに、
if( i ) のような書き方をすべきなのです。

さらに、デクリメント演算はif文の中に入れてしまう。
ただし、0の時の処理はif文直下(else内ではないという意味)に来るようにする。
つまり、if( ! --i )とします。

まとめると、

if( ! --i )
    処理B
else
    処理A

と書きます。

コンパイルされたアセンブラは以下のようになります。

  decfsz i,f
  goto else

  処理B
  goto end_if

else

  処理B

end_if

decfszは、
iから1ひいたものをiに入れ、その値が0なら次の命令を飛ばす
というものです。
1つの命令で、mov命令もsub命令も、条件判定もしてくれるので
高速でROMの節約にもなります。

 


 

論理を逆にして
if( --i )
    処理A
else
    処理B
としても良さそうですが、
コンパイラは処理A → 処理Bの順で翻訳するので(自動的に入れ替えてくれない)
余計な処理が入ります。

 


 

ポイントをまとめると

  • 回数の決まった処理では減算カウントをする
  • デクリメントの処理はif文のなかに
  • 0になった時の処理はifブロックに、0以外ではelseブロックに
  • 結果的に条件節は否定(!)になる。
  • アセンブラリストでdecfszに変換されているかチェックする。
というようになります。

 

この原則を守ると、可読性が失われる時もありますが、
処理の高速化やROMの節約にもなります。


コーディング時に考えるのは難しいので、
後でアセンブラリストを見て、考えるのでもいいと思います。

PR

コメント
ccsc
RVNさん、こんにちは。ccscの良いコーディング、勉強になります。ccsc ver4のマニュアルにもやはり
if (i == 0)
ではなくて、
if (!i)
のほうが節約できる旨の記述がありました。
ccscについて、わからないことが多く
これからも教えていただけるとありがたいです。
よろしくお願いします。
【2008/09/10 23:07】 NAME[je7ifp] WEBLINK[] EDIT[]


コメントフォーム
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字


トラックバック
この記事にトラックバックする:


忍者ブログ [PR]
カレンダー
07 2017/08 09
S M T W T F S
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
プロフィール
コールサイン:
JQ2RVN
性別:
男性
自己紹介:
PICの開発を勉強中です。
目標はPICTNCの高性能版を作ること。
まずは、本家を解析しています。
最新コメント
[04/23 Eolande]
[04/16 太田和巳(JF2UJG)]
[09/10 je7ifp]
[08/06 JQ2RVN]
[08/03 OVC]
最新トラックバック
バーコード
ブログ内検索
アクセス解析