マイクロコンピュータH8の構成と機械語プログラムの動作

10Sep2008
coskx

1.はじめに
 マイクロコンピュータH8(MPU,Micro Processing Unit)の構成と機械語プログラム動作の基本的なことについて説明する。
 この文書ではマイクロコンピュータH8の構成をイメージとして述べる。正確さは犠牲になるが,最初に学ぶ上ではイメージを大切にすることにする。

2.マイクロコンピュータH8の構成と動作
 マイクロコンピュータH8の基礎部分を単純化すると,

(1)CPU(central processing unit)
(2)メモリ
(3)I/Oレジスタ(入出力用レジスタ)

になる。
CPUは複数の汎用レジスタとプログラムカウンタ(PC)とスタックポインタ(SP),コンディションコードレジスタ(CCR)でできている。
メモリにはプログラム(機械語命令の羅列)やデータがバイト単位で置かれている。

 CPUはメモリのある部分に書いてある機械語命令(Instruction 1命令が数バイトで構成されている)を読み出し,どのような命令かを解析し,命令どおりの作業を行う。
通常,プログラムは複数の命令でできており,メモリ中に書いてある順番に命令が実行される。
命令には,メモリ(データ領域)とレジスタ間のデータの移動(実際にはコピー)をおこなうものや,レジスタ内のデータに対する演算などがある。
詳しくはアセンブリ命令一覧マニュアルで調べられる。

 命令をメモリ中のどこのアドレスから読み出すべきかをCPUは知らなければならないが,命令を読み出すアドレスを覚えているのはプログラムカウンタ(PC)である。
このカウンタは1つの命令の実行が終わるたびに,その命令のサイズ分(何バイトでできているか)だけ値を増やして,次の命令の読み出しに備えるようになっている。
CPUはプログラム全体を見て動いているわけではなく,プログラムカウンタの指し示す命令を順に行っているにすぎない。

CPUによる命令の読み出し,解析,実行はCPUに与えられているクロック信号(25MHzの矩形波)に合わせて行われている。

次の例はプログラムカウンタ(PC)=FF200の時の例である。

アドレス 機械語 意味
FF200
FF206
7A07000FFF00
6B20000FF800
MOV.L      #H'000FFF00:32,ER7
MOV.W      @H'FF800:24,R0
プログラムカウンタ=FF200なので,FF200番地から7A07000FFF00を命令として読み込み,
実行した後,プログラムカウンタ=FF206になる。

最初の1バイトすなわち7Aを読み込んだ時に,この命令は6バイトの命令であることを
CPUは理解する。そのため,PCの値は6増えてFF206になる。

プログラムカウンタ=FF200の時の例

3.マイクロコンピュータのメモリ
 メモリの種類には大きく分けて,
  (1)RAM(random access memory,書き込み読み出し可能,電源を切ると記憶内容は失われる)
  (2)ROM(read only memory,通常は読み出しのみ可能,電源を切っても記憶内容は保たれる)
の2種類ある。H8マイクロコンピュータでは2種類のメモリが使われている。

 アドレスの若い番地にはROMが,アドレスの後ろの番地にはRAMが配置されている。
 アドレスの若い番地のROMというのは,実際にはROMではなくフラッシュメモリという電源を切っても記憶内容が失われないメモリが使われている。
 メモリはアドレスによって管理される。一般的な使い方ではフラッシュメモリの部分に機械語のプログラムや定数データが置かれ,プログラム中で変化するデータがRAM領域におかれる。

メモリの様子

参考

4.マイクロコンピュータの起動とメモリ
 マイクロコンピュータは起動時にプログラムカウンタ(PC)が初期化され,あるアドレスを指すようになり,その位置をプログラムの先頭アドレスとして最初の命令(instruction)が読みだされ,連続した作業が始まる。
 マイクロコンピュータH8ではメモリの一番先頭の4バイト(0x00000から0x00003)にあるデータは「最初に実行すべき命令が置いてあるアドレス」とするようになっているため,起動時にはこの4バイトをプログラムカウンタにセットするようになっている。
 H8CPUを動かそうとする場合は,機械語プログラムの先頭アドレスを0x00000から0x00003に書いておかなければならない。

メモリの様子 CPU起動のからくり


5.ジャンプ命令と条件ジャンプ命令
  通常の命令が1つ実行されるごとにプログラムカウンタの値は次の命令が格納されているアドレスをさすようになるが,ジャンプ命令の場合はジャンプ先のアド レスがプログラムカウンタに格納される。このことにより,次の命令の読み込みには変更になったプログラムカウンタの指すアドレスが使われるため,プログラ ムの流れがジャンプしたようになる。
 条件ジャンプ命令は直前の演算命令の結果がゼロになったとか結果がオーバーフローしたなどの場合にジャンプする命令である。直前の演算結果の特徴がコンディションコードレジスタ(CCR)に残っており,指定した条件を満足した場合にジャンプするようになっている。

ジャンプ命令


6.メモリに保存されているデータ

 1つのアドレスには8ビット(1byte)のデータが保存されてい る。たとえば01101100の8ビットデータは16進法では6Cであり,一般的には1byteのデータは16進数2ケタで表わされる。また,データ6C がアドレスFFFE0に保存されているとすると次のようになる。

1バイトデータ6CのアドレスFFFE0への保存

アドレス

データ

FFFDE

何かのデータ

FFFDF

何かのデータ

FFFE0

6C

FFFE1

何かのデータ

FFFE2

何かのデータ

 C言語のlong int型のデータは,4バイトのデータであり,16進法では8ケタとなる。たとえばデータ1A2B3C4Dは16進法であらわしたlng int型の値であるが,このデータがアドレスFFFDEに保存されている状態とは,次のようにFFFDEからFFFE1の4バイトの領域に保存されている。

4バイトデータ1A2B3C4DのアドレスFFFDEへの保存
ビッグエンディアン(big endian)

アドレス

データ

FFFDD

何かのデータ

FFFDE

1A

FFFDF

2B

FFFE0

3C

FFFE1

4D

FFFE2

何かのデータ

 マイクロコンピュータH8ではこのように若いアドレスに上位のバイトデータから順に保存されている。
このようなメモリの使い方はビッグエンディアンと呼ばれモトローラの系統のCPUはこの方法をとっている。
一方逆順に保存するリトルエンディアンはインテル系統のCPUで見られる。

4バイトデータ1A2B3C4DのアドレスFFFDEへの保存
リトルエンディアン(little endian)

アドレス

データ

FFFDD

何かのデータ

FFFDE

4D

FFFDF

3C

FFFE0

2B

FFFE1

1A

FFFE2

何かのデータ


7.スタックとスタックポインタ

 通常値をメモリに保存するときには,アドレスを指定して値を保存する。保存した値を読みだすときは,保存したときのアドレスを指定して,読みだす。
しかし,もっと手早く,値をちょっとメモリに保存して,すぐに読み出す場合は,スタックというメモリ(RAM)の使われ方がある。
 スタックでは,複数の値を保存することができるが,読み出しの順番は,最後に保存した値が最初に取り出され,最初に保存した値は最後に取り出される。この構造はFILO(first in last out)と呼ばれている。
 メモリのRAM領域にFILO(first in last out)のスタックが形成されている。CPUの持つスタックポインタ(SP)が常に保存用作業メモリを指しているようになっている。すなわちCPUはハードウエアとしてスタックを持っていることになる。
  H8CPUの場合,データは2バイ トあるいは4バイトずつ保存されることになっており,データはメモリ上のアドレスで後ろから若いアドレスに向けて保存されるようになっている。CPU起動 後すぐにスタックポインタの初期化(ある値を設定する)を行う。データを登録することをpush,取り出すことをpopという。
 例えばスタック ポインタが最初に0xfff10で初期化されている場合,4バイトデータをpushすると0xfff0cから0xfff0fに保存され,スタックポインタ は0xfff0cになる。もう1つデータをpushすると0xfff08から0xfff0bに保存され,スタックポインタは0xfff08になる。またこ こでpop作業をすると,0xfff08から0xfff0bに保存されているデータが取り出され,スタックポインタは0xfff0cになる。すなわちスタックポインタは,値を取り出すべきアドレスを覚えていることになっている。
何回pushして何回popしたかはプログラマの責任であり,popの回数がposhの回数より多くなると不具合を起こす。

スタックの変化 (データは4バイトでpush/popされている場合)



8.サブルーチンコールとリターン
 機械語プログラムにおいても, C言語の関数呼び出しのようなプログラムの流れがある。機械語プログラム中にサブルーチンコール命令があると,サブルーチンにプログラムの流れが移り,サブルーチン中にリターン命令があると,先ほどサブルーチンコール命令の次の命令の位置にプログラムの流れが戻る。
 サブルーチンコール命令はジャンプ命令のように,ジャンプ先のアドレスをプログラムカウンタに載せてジャンプするが,その時,ジャンプ命令の次に書いてある命令のアドレスをスタックに保存するところが,ジャンプ命令と違うところである。
  サブルーチンの終りにはリターンン命令がある。リターン命令の実行はスタックからデータを取り出し,取り出した値をプログラムカウンタに載せる作業とな る。これによりサブルーチンリターン命令の実行の時に,サブルーチンコール命令の次に書いてある命令のアドレスをスタックに入れておいたものが取り出さ れ,プログラムカウンタに書き込まれるので,リターン命令の次に実行される命令は,サブルーチンコール命令の次に書いてある命令に戻ってくることになる。 CPUはプログラム全体を見てサブルーチンコールをしているわけではなく,スタックをうまく使い,プログラムカウンタの指し示す命令を順に行なうことによ りサブルーチンコールを実現している。

 

 

サブルーチンコールでは,命令51のアドレスが
スタックに保存され,プログラムカウンタはsssの
アドレスにされ,ジャンプする。

 

 

 

サブルーチンからのリターンでは,スタックに保
存されていたアドレスがプログラムカウンタの
値とされて,戻りジャンプする

サブルーチンコール命令とリターン命令