AKI-H8/3048
のモニタプログラム環境での
はじめてのプログラ
ミング簡単コマンド利用版
Copyright(C)29Dec2010
since 1Aug2003
coskx
1.はじめに
この文書は,AKI-H8におけるH8/3048のモニタプログラム,PCターミナルソフトでの学習を
記述しています。
モニタプログラムは,新しいプログラムの動作を検証する場合や,アセンブリ言語の学習者が,1命令ずつ機械語命令を実行してCPUのふるまい
を観察するプログラムです。モニタプログラムはROM(フラッシュメモリ)上に配置されており,検証対象のプログラムはRAM上に置かれま
す。検証対象のプログラムはモニタプログラム実行時に直接アセンブリ言語を書き込むか,PC上のエディタでアセンブリ言語プログラムを作り,
クロスアセンブラなどを用いて機械語プログラムをH8に転送されます。
第1段階としてモニタプログラム,PCターミナルソフト,クロスアセンブラ環境を構築します。
第2段階としてモニタプログラム上でアセンブリ言語によるH8プログラミングを学を学びます。アセンブリ語のプログラミングについては別の
文書で学んでください。この文書では
PC上のターミナル画面からアセンブリニーモニックを直接入力してCPUの動
作を見る方法
を示しています。
(本校)校内からは授業に使うため準備用ファイルが入手できます。この2つのファイルを入手して準備が出来たら「2モニタソフトの実行ま
で」に進んでください。
(本校)演習室の授業では trial4 をダウンロードします。
このファイルを解凍すると「trial4」のフォルダが出てくるので, |
(本校)内部LANからは環境整備のためのファイルがダウンロードできます。
|
このファイルを解凍すると「h8v2」のフォルダが出てくるので, 「C:\program files」の中に入れてください |
前提
(1)「トランジスタ技術2002年3月号付録CDROM」より入手した,アセンブラ,Cコンパイラ関
係ファイルおよびインクルードファイル,ライブラリファイルはすべて「C:\Program
Files\h8V2」に入っているものとします。
(2)MONITOR3048N.MOTをルネサステクノロジから入手済とします。利用条件を承諾してダウンロードできます
MONITOR3048N.MOTはルネサステクノロジが公開しているモニタソースをHEWでコンパイ ルしたものです。
(3)two2neg.exeを入手済とします。
「two2neg.exe」の取得は
http://www.vector.co.jp/soft/other/h8/se298946.htmlになります。
(4)転送ソフト「h8w.exe」を利用します。h8w.exeの入っているフォルダ「H8W」は「C:\Program
Files\h8v2\WRITER\H8W」を想定しています。
転送ソフト「h8w.exe」はyamasan氏のオープンツールです。次の場所から入手できます。
http://ym3.plala.jp/yamasan/
注意
この文書で扱っているAsm2Mon.cmdはWindows2000,WindowsXP,WindowsVista,Windows7,Windows8で
使用可能である。
2.モニタプログラムの実行まで
(1)作業用フォルダ trial4 をCドライブのルートに移動し,この中で作業します。
(全角のフォルダ名は問題を起こすようです)
(2)作業用フォルダを開きます。
(3)goH8W3048.cmdにて
MONITOR3048N.MOTを書き込む。
詳しく説明すると次のような手順になる。
WindowsPC側 | AKI-H8側 |
シリアルケーブルがCOM1に接続されていることを確認する。 | シリアルケーブルが接続されていることを確認する。 |
電源をOFFにする。 | |
Run/Write(Run/Boot)切り替えスイッチをWriteモードにする。 | |
電源をONにする。 | |
「MONITOR3048N.MOT」を「goH8W3048.cmd」にドラッグ&ドロップする。 |
|
転送終了まで待つ。 | |
電源をOFFにする。 | |
Run/Write(Run/Boot)切り替えスイッチをRunモードにする。 |
(4)「to_H8mon.ht」にて「ハイパーターミナル」
を立ち上げる。
teratermを使うときは,teraterm_H8_mon.cmdでteratermをを立ち上げる。
(5)起動手順での注意事項
ハイパーターミナル起動時にダイアログが開いて何か聞いてきたら |
起動時,地域の局番のところで,「03」を入力。 その他はすべて「次へ」「OK」でよい。 |
(6)AKI-H8をrunモードで起動し,次の表示が現れたらOKである。モニタが応答している。
モニタの起動
H8/3048 Series Advanced Mode Monitor Ver. 3.0A
Copyright (C) 2003 Renesas Technology Corp.
:
モニタのhelp
: ?
Monitor Vector 00000 - 000FF
Monitor ROM 00100 - 059F9
Monitor RAM FEF10 - FEFE3
User Vector FF000 - FF0FF. : Changes contents of H8/300H registers.
A : Assembles source sentences from the keyboard.
B : Sets or displays or clear breakpoint(s).
D : Displays memory contents.
DA : Disassembles memory contents.
F : Fills specified memory range with data.
G : Executes real-time emulation.
H8 : Displays contents of H8/3048 peripheral registers.
L : Loads user program into memory from host system.
M : Changes memory contents.
R : Displays contents of H8/300H registers.
S : Executes single emulation(s) and displays instruction and registers.
:
(8) ログファイル出力設定を行うと,モニタ画面上の表示と同じものがログファイルに書き出され,
報告書作成に便利である。
ハイパーターミナル | teraterm |
「転送」メニューの「テキストのキャプチャ」コマンド でファイル名を設定し,「開始」ボタンを押す。 キャプチャを停止するときは,「転送」メニューの 「テキストのキャプチャ」コマンドで「停止」 | 「ファイル」メニューの「ログ」コマンドで ログ出力ファイル名を設定する。 |
3.AKI-H8におけるCPU内のレジスタとメモリ配置
実際にプログラムを動作させる前に,簡単にH8のレジスタとメモリについて説明する。
3.1 レジスタ
レジスタはCPUの作業を行う場所である。(何ができるかは後で順に紹介する)
レジスタは32ビット幅で8個あり,名前はER0,ER1,ER2,ER3,ER4,ER5,ER6,ER7である。
またER0は,2つの16ビット幅レジスタE0,R0として使うこともできる。
(従って,R0とER0を同時に別の用途に使うことはできない)
さらにまた16ビット幅レジスタR0は,2つの8ビット幅のレジスタR0H,R0Lとして使うこともできる。
(従って,R0LとR0やER0を同時に別の用途に使うことはできない)
または
ER0 (32bit)
または
E0 (16bit)
R0 (16bit)
レジスタER0の構造と使われ方
E0 (16bit)
R0H (8bit)
R0L (8bit)
ER0の構造はER1,ER2,ER3,ER4,ER5,ER6でも同じである。
ここで,先のモニタでrコマンドを使ってレジスタの内容を表示 させてみよう。
モニタの起動
H8/3048 Series Advanced Mode Monitor Ver. 3.0A
Copyright (C) 2003 Renesas Technology Corp.
: r
PC=000000 CCR=80:I....... SP=000FFF00
ER0=00000000 ER1=00000000 ER2=00000000 ER3=00000000
ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00ここでER0=00000000 と表示されているのが, レジスタER0の内容である。16進8ケタでER0=0を表している。
(1byte=8bitは16進で2ケタ,2byte=16bitは16進で4ケタ,4byte=32bitは16進で8ケタで表され る。)
もし,ER0=12345678 と表示されているとすれば,次の3つの可能性がある。
(1)ER0=12345678
(2)E0=1234 R0=5678
(3)E0=1234 R0H=56 R0L=78
3.2 メモリ配置
AKI-H8はH8/3048をモード7で使用しているので,以下のようなメモリ配置になっている。
ROM領域 00000-1FFFF (128kbyte,フラッシュメモリ)
ベクタエリア 00000-000FF
ユーザエリア 00100-1FFFF (ここでいうユーザエリアにはモニタプログラムも含まれる)
RAM領域 FEF10-FFF0F (4kbyte)
ユーザエリア FEF10-FFEFF (ここでいうユーザエリアにはモニタプログラムも含まれる)
特別なRAM領域 FFEFF-FFF0F
このうち,モニタプログラムが動作している状況ではユーザのプログラム,データはすべてRAM領域を使う。
しかもモニタの作業領域もあるため,ユーザに開放されているのは次の範囲である。
ユーザベクタ FF030 - FF12F
プログラム,データ,スタック FF130-FFEFF
3.3 推奨されるメモリ割り当て
そうするとモニタを利用した短い学習用プログラムでは以下の利用方法が推奨される。
プログラム領域 FF130-FF7FF (1.75kbyte-48byte)
データ領域 FF800-FFDFF (1.5kbyte)
スタック領域 FFE00-FFEFF (0.25kbyte)
スタックポインタ初期値はFFF00(レジスタではFFFF00),先頭番地はめやすである。
メモリMAP
00000
?000FFROM ベクタエリア(モニタプログラム用) 00100
?1FFFFROM モニタプログラムエリア 20000
?FEF0Fメモリ非実装領域 FEF10
?FF02FRAM モニタプログラム作業領域 FF030
?FF12FRAM ユーザベクタ領域 FF130
?FFEFFRAM ユーザ領域
プログラム
データ
スタックFFF00
?FFF0FRAM 特別(8ビットアドレスによる高速アクセス領域) FFF10
?FFF1B未使用 FFF1C
?FFFFFI/O I/O領域
参考1 ユーザ領域でのプログラム,データ,スタックの境界は変更できる。
参考2 モニタプログラムを用いないAKI-H8利用方法ではプログラムはROM領域を,動的データはRAM領域を使用するので,サイズはそ
れぞれ128kbyteと4kbyteが利用可能となっている。
モニタプログラムでdコマンドを使ってメモリの様子を表示してみよう。表示するアドレスは0番地から1F番地とする。
モニタの起動
H8/3048 Series Advanced Mode Monitor Ver. 3.0A
Copyright (C) 2003 Renesas Technology Corp.
: r
PC=000000 CCR=80:I....... SP=000FFF00
ER0=00000000 ER1=00000000 ER2=00000000 ER3=00000000
ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00
: d 0 1f
<ADDR> < D A T A > < ASCII CODE >
00000 00 00 01 00 00 00 28 16 00 00 28 1A 00 00 28 1E "......(...(...(."
00010 00 00 28 22 00 00 28 26 00 00 28 2A 00 00 28 2E "..("..(&..(*..(."これは,0,1,2番地の値が順 に,00,00,01,00,00,00,28,16,...となっていることを示している。
また,1B番地は2A,1F番地は2Eであることもわかるであろう。
4.テストプログラムの入力と実行
(1)ここでは簡単なテストプログラムの入力と実行を行なう。
メモリ上におかれた2つの整数の和を作り,別のメモリに格納する。
プログラムは次のようなものである。
プログラムはFF200番地から格納する。
スタックポインタを初期化する(使わないのでしなくてもよい)
FF800番地の2byteデータをレジスタR0に載せる
FF802番地の2byteデータをレジスタR1に載せる
R0とR1の値を加えてR0にしまう
R0のデータをFF804番地にしまう
(2)実行の手順
1)プログラムニーモニックの手入力
2)FF800,FF802,FF804番地に適当なデータをしまう
3)FF800,FF802,FF804番地の内容を確認する
4)1ステップずつプログラムを実行する
5)FF800,FF802,FF804番地の内容を確認する
(3)実行時のモニタの画面
ここではプログラムをFF200から置いて実行させている。
内容 |
モニタ画面 |
|
プログラムの入力 アセンブリプログラムを入力すると,モニタプログラムが,機械語に変換しながら |
: a ff200 FF200 > mov.l #fff00,er7 FF206 > mov.w @ff800:24,r0 FF20C > mov.w @ff802:24,r1 FF212 > add.w r1,r0 FF214 > mov.w r0,@ff804:24 FF21A > bra ff21a:8 FF21C > . |
|
書き込まれた機械語プログラムの確認表示 しかし,人間には意味不明 |
: d ff200 ff21f <ADDR> < D A T A > < ASCII CODE > FF200 7A 07 00 0F FF 00 6B 20 00 0F F8 00 6B 21 00 0F "z.....k ....k!.." FF210 F8 02 09 10 6B A0 00 0F F8 04 40 FE FF F9 FF F7 "....k.....@....." |
|
プログラムの確認 (DisAssemble ディスアセンブル) 「da ff200 ff21a」はFF200番地から FF21A番地までのメモリ内の値を機械語プログラムだとして,アセンブリ言語に翻訳し表示しなさいの意味。 FF200からFF21Aまでをモニタプログラムに翻訳,表示させたことになる。 先に表示された機械語の羅列と同じものが見えている。 |
: da ff200 ff21a <ADDR> <CODE> <MNEMONIC> <OPERAND> FF200 7A07000FFF00 MOV.L #H'000FFF00:32,ER7 FF206 6B20000FF800 MOV.W @H'FF800:24,R0 FF20C 6B21000FF802 MOV.W @H'FF802:24,R1 FF212 0910 ADD.W R1,R0 FF214 6BA0000FF804 MOV.W R0,@H'FF804:24 FF21A 40FE BRA FF21A:8 |
|
ff800番地付近の メモリ表示 (設定前) *1 まだなにもしていないため,各番地にどのような値が保存されているかは不明で,実際にはこれとは異なる値が表示される。 |
: d ff800 ff80f <ADDR> < D A T A > < ASCII CODE > FF800 12 34 23 45 35 79 DB 7B E2 8C E7 5B 04 80 E7 7A ".4#E5y.{...[...z" |
|
ff800番地付近の |
: m ff800 FF800 12 ? 11 FF801 34 ? 22 FF802 23 ? 33 FF803 45 ? 44 FF804 35 ? 55 FF805 79 ? 66 FF806 DB ? . |
|
ff800番地付近の |
: d ff800 ff80f <ADDR> < D A T A > < ASCII CODE > FF800 11 22 33 44 55 66 DB 7B E2 8C E7 5B 04 80 E7 7A "."3DUf.{...[...z" |
|
レジスタの確認 *3 SPとER7は同じレジスタである |
: r PC=0FF11A CCR=80:I....... SP=000FFF10 ER0=00000000 ER1=00000000 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF10 |
|
プログラムカウンタ (PC)の変更 *2 |
: .pc PC=0FF11A ? 0ff200 CCR=80 ? . |
|
レジスタの確認 | : r PC=0FF200 CCR=80:I....... SP=000FFF10 ER0=00000000 ER1=00000000 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF10 |
|
1ステップずつ 実行 *4 |
: s PC=0FF206 CCR=80:I....... SP=000FFF00 ER0=00000000 ER1=00000000 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00 FF200 7A07000FFF00 MOV.L #H'000FFF00:32,ER7 : s PC=0FF20C CCR=80:I....... SP=000FFF00 ER0=00001122 ER1=00000000 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00 FF206 6B20000FF800 MOV.W @H'FF800:24,R0 : s PC=0FF212 CCR=80:I....... SP=000FFF00 ER0=00001122 ER1=00003344 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00 FF20C 6B21000FF802 MOV.W @H'FF802:24,R1 : s PC=0FF214 CCR=80:I....... SP=000FFF00 ER0=00004466 ER1=00003344 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00 FF212 0910 ADD.W R1,R0 : s PC=0FF21A CCR=80:I....... SP=000FFF00 ER0=00004466 ER1=00003344 ER2=00000000 ER3=00000000 ER4=00000000 ER5=00000000 ER6=00000000 ER7=000FFF00 FF214 6BA0000FF804 MOV.W R0,@H'FF804:24 |
ER7の設定変化したが わかりにくい ER7の値はそのままSP の値でもある ER0の下位4桁 はR0を示している もとはFF800にあった値 ER1の下位4桁 はR1を示している もとはFF802にあった値 ER0の下位4桁はR0, ここに和 が格納された アドレスFF804に R0の値が格納 されたはず |
ff800番地付近の |
: d ff800 ff80f <ADDR> < D A T A > < ASCII CODE > FF800 11 22 33 44 44 66 DB 7B E2 8C E7 5B 04 80 E7 7A "."3DDf.{...[...z" |
*1 ビッグエンディアン:十六進数0x1122はメモリ上で 11,22の順で並んでいる。
*2 「.」を打つとそれ以降の変更作業は終了 変更しないときは,単に[ret]を押す。
*3 レジスタの表示について
PC | プログラムカウンタ 24ビット(16進表現で6ケタ) H8/3048のモード7(現在の使用方法)では20ビット16進表現で5ケタ)のみ使用 |
CCR | コンディションコードレジスタ 8bit(16進表現で2ケタ) 割り込みマスクはこのレジスタの第7bit(I) |
SP | スタックポインタ 32ビット(16進表現で8ケタ) 実はER7と同 じもの |
ER0? ER7 |
7つのレジスタ 32ビット(16進表現で8ケタ) |
Bの命令とは FF200番地に書いてある「7A07000FFF00」の ことで,CPUはこれを読み取って動作している。 その意味は「MOV.L #H'000FFF00:32,ER7」であると,モニタプログラムが人間にわか るように翻訳してくれている。(CPUがこれを見ているわけではない) |
*5プログラムの説明
mov.l #fff00,er7 mov.w @ff800:24,r0 mov.w @ff802:24,r1 add.w r1,r0 mov.w r0,@ff804:24 bra ff21a:8 |
値FFF00をレジスタer7(スタックポインタ)に格納 |
「.l」はlongword(4バイト)の意味 「.w」はword(2バイト)の意味 「.b」はbyte(1バイト)の意味 |
スタックポインタはサブルーチンコール時の戻りアドレスなど重要な内容の格納場所を示すレジスタなので,
CPU起動時にスタック領域の一番後ろを指すようにしておく。
MOV.L #H'FFF10,ER7 ;スタックポインタ設定 |
言葉の説明
アセンブリ言語
(人間が理解できる)
mov.l #fff00,er7
mov.w @ff800:24,r0
mov.w @ff802:24,r1
add.w r1,r0
mov.w r0,@ff804:24
bra ff21a:8→→→
翻訳作業の名前
「アセンブル」
翻訳プログラムの名前
「アセンブラ」←←←
翻訳作業の名前
「ディスアセンブル」
翻訳プログラムの名前
「ディスアセンブラ」機械語
(CPUが理解できる)
7A 07 00 0F FF 00 6B 20
00 0F F8 00 6B 21 00 0F
F8 02 09 10 6B A0 00 0F
F8 04 40 FEモニタプログラム内には,アセンブラ,ディスアセンブラが 組み込まれていた。
H8
命令ニーモニクの説明マニュアル 学内高速読み取りバッファより
7.参考(1) 各コマンドの説明
モニタにおいて,コマンドの後ろに「?」をつけると各コマンドの説明が表示されます。
各コマンドのhelp |
: b ? 1. Sets breakpoint at specified address. B <address> [RET] 2. Displays breakpoint(s). B [RET] 3. Clear breakpoint(s). B - [<address>] [RET] <address> : address of breakpoint : d ? Displays memory contents. D <address1> [<address2>] [;<size>] [RET] <address1> : dump area start address <address2> : dump area end address <size> : B -- byte W -- word L -- long word : f ? Fills specified memory range with data. F <address1> <address2> <data> [RET] <address1> : filling area start address <address2> : filling area end address <data> : filling byte data : h8 ? Displays contents of H8/3048 peripheral registers. H8 <name> [RET] <name> : DMAC0 - Direct Memory Access Controller 0 DMAC1 - Direct Memory Access Controller 1 ITU - 16bit Integrated Timer pulse Unit ITU0 - 16bit Integrated Timer pulse Unit 0 ITU1 - 16bit Integrated Timer pulse Unit 1 ITU2 - 16bit Integrated Timer pulse Unit 2 ITU3 - 16bit Integrated Timer pulse Unit 3 ITU4 - 16bit Integrated Timer pulse Unit 4 TPC - programmable Timing Pattern Controller WDT - Watch Dog Timer SCI0 - Serial Communication Interface 0 SCI1 - Serial Communication Interface 1 I/O - I/O port D/A - D/A converter A/D - A/D converter INTC - INTerrupt Controller BSC - BuS Controller,etc. : |
8.参考(2) アッセンブルコマンド「Asm2Mon.cmd」
Asm2Mon.cmd |
rem
------------------------------------------------------------------------ @echo off rem カレントドライブ・カレントディレクトリへ移動 rem コンパイラのパスの設定 rem
誤ったファイルがドロップされたか,単なるダブルクリックで起動した場合は何もしない :ASSEMBLE :LINK :CONVERT goto TERMINAL :NO_SOURCE_ERROR :ASM_ERROR :LINK_ERROR :TERMINAL |
9.参考(3)h8v2フォルダの構成例
h8v2の構成例 |
C:\Program Files\h8v2 ├─BIN │ ASM38.EXE │ C38ASM.EXE │ C38CGN.EXE │ C38FRNT.EXE │ C38MID.EXE │ C38PEP.EXE │ CH38.EXE │ CNVS.EXE │ h8v2cc.cmd │ LNK.EXE │ OPT38.EXE │ OPTLNK38.EXE │ ├─INCLUDE │ 3048F.H │ 3048FONE.H │ 3048S.H │ 3664S.H │ ASSERT.H │ CTYPE.H │ ERRNO.H │ FLOAT.H │ INDIRECT.H │ LIMITS.H │ MACHINE.H │ MATH.H │ NO_FLOAT.H │ SETJMP.H │ STDARG.H │ STDDEF.H │ STDIO.H │ STDLIB.H │ STRING.H │ ├─LIB │ │ C38HA.LIB │ │ C38HAS.LIB │ │ C38HN.LIB │ │ C38HNS.LIB │ │ C38REG.LIB │ │ C38REGS.LIB │ │ C8S26A.LIB │ │ C8S26AS.LIB │ │ C8S26N.LIB │ │ C8S26NS.LIB │ │ start3048.OBJ │ │ start3048I.OBJ │ │ │ |