Z80ユーザーに贈るH8マシン語入門

H8のページに戻る



レジスタ構成を知ろう

レジスタは、以下のように特殊なレジスタと汎用レジスタに分けられます。

・特殊なレジスタ

 以下の特殊なレジスタは、ビット数こそ違うもののZ80とほぼ同じ働きをします。

H8のレジスタ

相当するZ80のレジスタ

PC(24ビット)

PC

ER7(32ビットだが実質24ビットしか使わない)

SP

CCR(8ビット)

フラグレジスタ



・汎用レジスタ

 汎用レジスタは、ER0〜ER6の、32ビット×7本です。これらは上下16ビットづつに分割して、E0〜E6、R0〜R6の14本の独立した16ビットレジスタとして使うこともできます(ここが80386や68000などと比べて便利な点です。たとえば80386などは、EAXの上位16ビットを独立したレジスタとして扱えません)。さらに、R0〜R6の7本の16ビットレジスタは、上位バイトと下位バイトに分けてR0H〜R6H、R0L〜R6Lという14本の独立した8ビットレジスタとして使うこともできます。その辺の関係をER0を例にとって表にすると、以下のようになります。

32ビットレジスタ

ER0

16ビットレジスタ

E0(上位)

R0(下位)

8ビットレジスタ


R0H

R0L



 基本的にすべての汎用レジスタは対等です。使用できるレジスタが固定されているのはEEPMOV命令(LDIR相当)だけです。Z80のようにAやHLがひいきされていたりしません。

アドレッシングモード

 H8は結構68000と似たCPUですが、68000のような複雑怪奇なアドレッシングモードはありません。Z80のアドレッシングモードが理解できた人なら問題ないでしょう。ただ、アセンブラの表記は異なります。以下はZ80とほぼ同じアドレッシングモードです。

アドレッシングモード

H8

Z80

イメーディエート

MOV.B  #H'12,R0L
LD  A,012H

レジスタ直接

MOV.B  R1H,R0L
LD  A,B

絶対

MOV.B  @H'001234,R0L
LD  A,(01234H)

レジスタ間接

MOV.B  @ER3,R0L
LD  A,(HL)

ディスプレースメント(オフセット)つきレジスタ間接

MOV.B  @(10,ER3),R0L
LD  A,(IX+10)

プログラムカウンタ相対

BRA    label
JR  label


 目新しいアドレッシングモードとしてはポストインクリメント、プリデクリメントのレジスタ間接があります。これは、メモリアクセスとポインタのインクリメント/デクリメントを1つの命令でやってくれるのです。

ポストインクリメントレジスタ間接

MOV.B  @ER3+,R0L
LD   A,(HL)
INC  HL

プリデクリメントレジスタ間接

MOV.B  R0L,@-ER3
DEC  HL
LD   (HL),A


 なお、気を付けなければいけないのは、ポストインクリメントは「メモリ→レジスタ」のみ、プリデクリメントは「レジスタ→メモリ」のみ、と転送方向が限られています。これらのアドレッシングモードは「連続データ転送」などよりも「ソフトウエアスタック」を目的として設けられたようです。

 あと、メモリ間接というのもありますが、データのアクセスには使えず、ジャンプ、コール(JSR)のみで使えます。8086のINT命令みたいな感じです。

移植の際の注意

・メモリーレジスタ間の演算はできない

	MOV.B	@ER3,R0H
	ADD.B	R0H,R0L

・転送しただけでゼロフラグ、符号フラグが変わる

・交換命令がない

・条件コール、条件リターンがない

・EEPMOVについて

・ポインタのインクリメント・デクリメントにはADDS/SUBSを使おう

	INC.L	#2,ER3		; ER3に2を足す
	INC.L	#2,ER3		; ER3に2を足す
	ADDS	#4,ER3


こりゃ楽でいいや

 H8はZ80よりはるかにすぐれている点があります。そういった点を積極的に使いましょう。

・どのレジスタでも論理演算できる、しかも、2バイト、4バイトの演算も1命令でできる!

・2バイト数値、4バイト数値のイメーディエイト演算ができる!

・2バイト数値、4バイト数値のレジスタ間接アクセスが1命令でできる!

	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	INC	HL
	MOV.W	@ER3+,R2