今までの流れを説明しておきます。CPUレジスタ、とくにアキュムレータの実際の使われ方を見る目的で、簡単な足し算をアセンブリ言語を使って記述し、それをステップ実行で確かめています。
今回はその続きを見たあと、同じことをC言語を使ってやってみます。C言語のソース・レベルでステップ実行をした場合はアキュムレータの動きはわかりませんが、CodeWarrior のデバッガはC言語で書いてあってもアセンブリ言語レベルでステップ実行をすることができるので、アキュムレータの動きを見ることが可能です。
ということで、まずは前回の続きです。 【Single Step】 アイコンを何度かクリックして BRA mainLoop のところまで進めてください(下図の位置)。 ちょっと面白い実験をしてみましょう。 このまま、44 + 55 の計算をしてみます。 Dataペインの VarA の値 「 4 」 をダブルクリックして、44 ENTER を入力してください。すると下図のようになります。
同様に、Dataペインの VarB の値 「 5 」 をダブルクリックして、55 ENTER を入力すると下図のようになります。
準備ができたところで 【Single Step】 アイコンを何度かクリックしてみると、44 + 55 = 99 が計算され、下図のように結果が VarC に格納されることが確認できます。
CPUレジスタとメモリを使った簡単な足し算の演習を行いました。 CPUレジスタの説明としてはまだまだ不充分なのですが、ここで深く掘り下げて周りがよく見えなくなってもよくないので止めておきます。
◆ C言語を使って簡単な足し算を試す
それでは、これをC言語で試すとどうなるか、やってみましょう。第6回 と同じ要領で、C: ドライブのルートにある HC08 フォルダに qy4a_test03 を作成してください(今回は absolute assembly に変える必要はなく、C言語のままでよい)。 できたら main.c をダブルクリックして開き、下図のように書き換えてください。 なお 「 // 」 から右はコメントなので、書いても書かなくても問題ありません。
もう見ればだいたいわかると思いますが、一応説明をしておきます。
unsigned char VarA, VarB, VarC; 1バイトの変数を 三つ定義しています。名前は VarA 、 VarB 、 VarC です。 なお、ANSI 準拠のC言語の場合は、この例のようにグローバル定義された変数はスタートアップ時に 0 に初期化されます。
VarA = 4;
VarB = 5; この 2行は、変数に値を入れています。数字をそのまま書けばよく、アセンブリ言語の即値のように#記号を付ける必要はありません。
VarC = VarA + VarB; 足し算を行い、その結果を変数 VarC に格納しています。
間違いなく書き換えたら、【Make】 アイコンをクリックしてメイクしてください。エラーや警告がなければ、HC08スターター・ボードの電源スイッチをオンにして、【Debug】 アイコンをクリックしてください。 P&E Connection Manager が出たら、第6回と同様にして進めます。デバッガ画面が出たら、第6回と同じようにしてフォントを日本語に変更しておきます。
アセンブリ言語のときと比べて、どう変わったか見てみます。
下図のように Data ペインの VarA をクリックして強調させてみてください。そのとき Address: 0x80 Size: 1 と出ましたので、この場合は Memory ペインの 0080 と書かれたところ、すなわち 0x0080 番地に配置されています。同様に、VarB、VarC はそれぞれ 0x0081番地、0x0082 番地になっています。内容は、すでに 三つとも 0 に初期化されています。実はこの時点でスタートアップ・ルーチンと呼ばれる処理を実行した状態で止まっているのです。
なお、これらの変数はアセンブリ言語で書いた場合と同じ番地になっていますが、必ずそうなると決まっているわけではありません。
【Single Step】 ではなく、【Assembly Step】 (上図) をクリックして一つずつ命令を進めていってください。アキュムレータとメモリ上の変数がちまちまと変わっていく様子が見られます。
下図で for ( ; ; ){ から始まって 3行下の } までが無限ループになっています。 その中の主な仕事である計算式 VarC = VarA + VarB; に相当するアセンブリ言語の命令を、Assembly ペインの青い四角で囲んで示しています。 【Assembly Step】 アイコンをクリックしながら、アキュムレータとメモリの変化を確かめてください。 追ってみると、先に VarB の値をアキュムレータに入れてから、VarA の値を足していますね。先ほどとは逆の手順ですが、もちろん答えは合っています。
44 + 55 も、そのままデータをダブルクリックして書き換えることで実行可能です。 444 + 555 は、そのままでは計算できません。 main.c を少し変更する必要があります。
unsigned char VarA, VarB, VarC; のところを、unsigned int VarA, VarB, VarC; として 2バイト変数にすればよいのです。変更したら、【Debug】 アイコンをクリックして、フラッシュROM を更新してから動かしてみてください。【Single Step】 を使って C言語のソース・レベルで 1行ずつ動かすととても簡単に見えますが、【Assembly Step】 で動かすと、かなり面倒な処理をやっていることが理解できるでしょう。
C言語で int と言えば integer すなわち整数型のことですが、そのサイズは、実は統一されたものではありません。原則として、16ビット・マイコンであれば int は 2バイト、32ビット・マイコンであれば int は 4バイトです。8ビット・マイコンの場合は、int が 16ビットのものが多いようです。なお、char はキャラクタ型といって、文字(英数字)が 一つ収められるサイズということから 1バイトとなっています。
次回は、周辺機能レジスタについて説明を始めます。
『参考文献』
「試しながら学ぶHC08マイコン入門」 (CQ出版)
第10章 統合開発環境CodeWarrior を使ってみる
組み込みエンジニア KAWANO
