FC2ブログ

関数呼び出しの様子

2012-12-24      
 今日も朝から懲りずに周波数カウンタに温度計を突っ込んで放っておき、時々眺めていました。結局、昨晩と同じような温度差(8~9℃程度カウンタ内部温度の方が高い)だということが判ったんで、次なる改良案へ・・・と思ったのですが、どうしてもPIC12Fシリーズが欲しくなり、次の秋葉行き(実は、25日に寄り道できそう)までお預けにしました(この辺りは、別のカテゴに譲ります)。

 さて、もう一つ同時並行的に進めているAD9834を使ったSG試作の方・・・禁断のC言語に手を出したばかりにその展開形(コンパイル後のニーモニックの様子)が気になり、プログラミング部分で停滞していますが、今日は関数呼び出し部分がどんな風になるのかを探ってみました。なお、パラメータについては8ビットPICでは最も使われるであろう「unsigned char型」についてのみの調査です。

 まず、パラメータが「unsigned char」×1つのタイプでは、呼び出し側のニーモニック・・・というか、コンパイル結果を逆アセンブラすると以下のようになっています(以下、unsigned char ⇒ uchar)。

関数 static void lcd_cmd(uchar out)の呼び出し

;lcd.c: 52: lcd_cmd(0b00000110);
    movlw    (06h)
    fcall    _lcd_cmd

 Wレジスタにパラメータをそのまま入れて直ぐに呼び出す形ですから、全く無駄がありません。一方、呼ばれる側はというと、以下のようになります。

関数 static void lcd_cmd(uchar out)の先頭

_lcd_cmd:
    movwf    (lcd_cmd@out)

 呼ばれる側・・・つまり関数の方では、Wレジスタで受け渡されたパラメータを「lcd_cmd@out」という変数に直ぐに代入していることが判ります。以降、この関数内では、パラメータが「lcd_cmd@out」に入っているという前提で処理されます。
 本当は、折角Wレジスタに入っている値をそのまま使って処理することもできるわけですが、後の処理で何度もこのパラメータを参照する場合には、結果的にどこかに置いて記憶しておかなければなりませんから、この展開形は特に問題ないでしょう。

 ところで、実際の処理の組み立てでは、上記のようなパラメータが1つしかない関数もさることながら、複数パラメータのものも多く見受けます。2つのパラメータを受け渡してみましょう。

関数 static void lcd_cmd(uchar mode, uchar out)の呼び出し

;lcd.c: 52: lcd_cmd(1,0b00000110);
    movlw    (06h)
    movwf    (??_lcd_init+0)+0  ←
    movf    (??_lcd_init+0)+0,w  ←
    movwf    (?_lcd_cmd)
    movlw    (01h)
    fcall    _lcd_cmd

 先頭のパラメータ「mode」は、Wレジスタで渡されますが、「out」の方は「?_lcd_cmd」という別の変数に置かれて渡されます。こうなると、相変わらず「余計な2ステップ」(上の囲みの矢印部分)が出てきてしまいますから、あまりパラメータを考え無しに多くすると冗長になりそうです。即ち、XC8を使う限り、関数の王道としては「unsigned char×1」が良さそうです。

 単機能の関数にパラメータを1つだけ渡す・・・所詮8ビットですから、まぁこんなもんでしょう。
関連記事

コメントの投稿

非公開コメント

Calendar
07 | 2019/08 | 09
Sun Mon Tue Wed Thu Fri Sat
- - - - 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
New !
Category
Comments
Monthly Archives
Track Backs
Counter
Sunspot Now !

 


Survey Results

 

Profile

どよよん無線技士

Author :どよよん無線技士
こおるさいん:JM1DPL

アパマンというハンデにさらにQRPまで課し、失敗連続のヘッポコリグや周辺機器の製作・・・趣味というより「荒行」か!?

メールは「JARL経由」でお願いします。

Links
Follow me !
RSS Links
QR Code
QR