HC08マイコンの CPUレジスタについて学習をしたので、早速それを実験で確かめましょう。 この連載では基本的にC言語を使って解説を進めますが、CPUレジスタの操作はC言語では書けませんから アセンブリ言語 を使うことにします。
◆ アセンブリ言語を使って簡単な足し算を試す
HC08スターター・ボードをデフォルトの設定にして、パソコンと接続しておいてください(まだ電源スイッチはオフのまま)。 CodeWarrior を起動して、新規のプロジェクトを作成します。 第6回に新規プロジェクトの作り方が書いてあります。 今回はアセンブリ言語を使うので、途中から少し様子が異なってきますから気を付けて進めてください。
Connection を選択するところまでは第6回で説明したのと同じ手順です。 次に使用する言語を選択します。 C言語のチェックを外してから、【Absolute assembly】 にチェックを付けてください。 プロジェクト名と格納位置を決めるために 【Set... 】 をクリックします。
例として、C: ドライブのルートに作った HC08 というフォルダの中に、qy4a_test02 を作成しました。【保存】 をクリックします。
下の画面のようになりました。【完了】 をクリックします。
統合開発環境(IDE)の画面が出てきますので、左の枠の中にある main.asm をダブルクリックして開いてください。 下図のあたりを書き換えてみることにします。
このプログラムに何が書かれているのか、簡単に説明しておきましょう。
; (セミコロン) から右はコメントなので、なくても同じです。
ORG RAMStart ここからはメモリ・マップ上の RAMの位置に配置したいものを書いていきますよ、という意味です。 QY4A では、デフォルトで $0080 番地になっています。
第12回の メモリ・マップ を参照 してください。
16進表記について、前々回と前回では FFh のような書き方をしていました。実は 16進表記にはいろいろな書き方が流通しています。末尾に h または H を付けるのは、昔ながらのインテル流と言ってよいでしょう。 フリースケールでは $FF のように先頭に $ (フォントによっては見にくいがエスではなくドル・マーク) を付ける、これまた昔ながらのモトローラ流の書き方を使っています。 ほかには、ルネサスのH8マイコン(旧・日立)のマニュアルで見られる H’FF のように先頭に H’ を付ける書き方がありました。 情報処理試験で使われる CASL では、FF(16) のように、後ろに (16) を付けて表しています。
ちなみにC言語では、0xFF または 0xff のように、先頭に 0x を付けて 16進数を表します。
ExampleVar: DS.B 1 1バイトの領域を 一つ確保しますよ、ラベル(名前)は ExampleVar ですよ、という意味です。
ORG ROMStart ここからはメモリ・マップ上の ROM(フラッシュROM)の位置に配置したいものを書いていきますよ、という意味です。 QY4A では、デフォルトで $EE00 番地になっています。
_Startup: ラベルです。ここでは、メモリ・マップ上の $EE00 番地(番地を示す数値) に _Startup という名前を付けています。 細かい話になりますが、今回の設定では、この値が前回説明した リセット・ベクタ に自動的に書き込まれます。
LDHX #RAMEnd+1
TXS
CLI
この 3行はスタック・ポインタ(詳しくは別の機会)の設定と割り込み許可の設定です。今回はスタックも割り込みも使いませんが、残しておいても害はありません。
mainLoop: ラベルです。この後に書いた命令がメモリ・マップ上に配置された位置(番地を示す数値) に適当な名前を付けたものです。
NOP No operation といって、何もしない命令です。時間待ちなどに利用します。
feed_watchdog COPタイマ(ウォッチ・ドッグ・タイマともいう)が時間切れでリセットしてしまわないようにする命令で、繰り返し使用します。 実はこれを書くと、STA $FFFF が実行されて目的を果たします。 なお、CodeWarrior でデバッグ中(モニタ・モードという)のときは時間切れを起こさないように作られています。
BRA mainLoop mainLoop ラベルの位置にジャンプします。
これを次のように書き換えてください。 変更個所は青い四角で囲んだ部分です。 文字の色は気にしないでください。
このプログラムの意味は、第11回の例題に基づいて 「 4 + 5 」 を計算しています。
VarA: DS.B 1
VarB: DS.B 1
VarC: DS.B 1
それぞれ、1バイトの領域を 一つずつ確保する、という意味です。それぞれにラベル(名前)を付けています。 これらを変数として使います。
MOV #4, VarA
MOV #5, VarB
それぞれ、
4 という数値を変数 VarA に入れます。
5 という数値を変数 VarB に入れます。 という意味です。
# が付くと、その数値そのもの (即値、immediate data) という意味
になります。 もしも # がなくて MOV 4, VarA と書いた場合は、
4番地の内容を VarA に入れる、という意味になるので注意が必要です。
LDA VarA VarA の内容をアキュムレータに入れます。
ADD VarB VarB の内容をアキュムレータに足します。結果はアキュムレータに保存されます。アキュムレータは 一つしかないので、その時点で VarA の内容はアキュムレータからは消えてしまいます。 VarA 、VarB の内容は、それぞれそのまま VarA 、VarB には残っています。
STA VarC アキュムレータの内容を VarC に入れます。 これが計算の答えになります。
この処理は、mainLoop から後の部分を繰り返すように書かれています。初期設定とも呼べる 4 と 5 を VarA と VarB に格納する部分は繰り返しには含まれていないことを覚えておいてください。
間違えずに main.asm プログラムの書き換えが済んだら、【Make】 アイコン(第7回を参照)をクリックして Make を行ってください。
(続く)
『参考文献』
「試しながら学ぶHC08マイコン入門」 (CQ出版)
第10章 統合開発環境CodeWarrior を使ってみる
組み込みエンジニア 川野亮輔
