W.I.S. Laboratory
menu-bar

CPU


Z80のFレジスタ(フラグレジスタ)は1バイトの一時保存領域として使えるか

本やサイトで見つかるZ80の仕様書は非常に詳しくて、「あれ?この命令でこのフラグは変化したっけ?」というときなどにとても助かっている。
何十年と知っているプロセッサなのだが、意外に細かい挙動などは頭に入っていないものだ。
仕様書には、Fレジスタ(フラグレジスタ)に関することも記されていて、以下のようになっている。

b7:S 符号
b6:Z ゼロ
b5:未使用 (0に固定)
b4:H AUXキャリー
b3:未使用 (0に固定)
b2:P/V パリティ・オーバーフロー
b1:N 減算(ADD命令で0、SUB命令で1)
b0:C キャリー

bit3とbit5は未使用であり、0に固定ということだが、この2bitに対しては「書き込もうとしても書き込めない」ということなのだろうか。
などと気になり始めてしまった。

ということで、ポケコンのPC-G850(Z80互換CPUであり、本家ザイログのZ80ではないが)で試してみた。
ついでにPC-8801エミュレータのM88でもやってみたが、エミュレータがどこまで本家のCPUを再現しているかは不明。(PC-8801MCの実機があるにはあるのだが、検証のために引っ張り出すのも面倒なので・・)
M88上で使用したアセンブラは、日高師匠の「HIT-88」だ。高校生の頃に購入したが、今もマスターを持っている。

di

exx
ld hl,0
add hl,sp ; 裏レジのHLに現在のスタックポインタの値を保存
exx

ld a,0ffh
ld hl,0800h
ld (hl),a
inc hl
ld (hl),a ; 0800h番地にffffを書き込む

ld sp,0800h
pop af ; 書き込んだffffを読み込む
ld sp,0804h
push af ; 隣の領域に書き込む

exx
ld sp,hl ; スタックポインタを復元
exx

ei
ret

早い話が、メモリの適当な場所に“FFFF”という2バイトの値を用意し、それをPOP命令でAFペアに格納後、PUSH命令で別の場所に書き込むというだけのもの。
PUSH命令は2バイトのプリデクリメントをするので、スタックポインタの値は実際に書き込むアドレス(0802H)より2つ大きく設定している。
もし、Fレジスタのbit3とbit5が0に固定されているのならば、PUSHした2バイトの値は“FFFF”ではなくなるはずだ。

実行前のモニタ画面。
結果が分かりやすいように、あらかじめPUSHする付近のRAMは0クリアしておく。

PC-G850のモニタ画面
M88のモニタ画面
実行後のモニタ画面。

PC-G850での実行結果
M88での実行結果

PC-G850は、0800番地の2バイトが元のデータ、そこからさらに2バイトがAFペアの内容。
M88は、D000番地の2バイトが元のデータ、そこからさらに2バイトがAFペアの内容。

どちらも“FFFF”になっている。
「もしかしたら1に固定かもしれない」とも思い、あらかじめ用意するデータを0000Hにして同じことをやってみた。
今度はちゃんと“0000”になる。

つまりこの2つの環境においてのみ言えば、フラグレジスタには8bit分のRAMが用意されていて、bit3とbit5は0に固定されていないということになる。
フラグレジスタを1バイト分の一時保存領域として使えるわけだ。

[ 戻る ]
saluteweb