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は、0800番地の2バイトが元のデータ、そこからさらに2バイトがAFペアの内容。
M88は、D000番地の2バイトが元のデータ、そこからさらに2バイトがAFペアの内容。
どちらも“FFFF”になっている。
「もしかしたら1に固定かもしれない」とも思い、あらかじめ用意するデータを0000Hにして同じことをやってみた。
今度はちゃんと“0000”になる。
つまりこの2つの環境においてのみ言えば、フラグレジスタには8bit分のRAMが用意されていて、bit3とbit5は0に固定されていないということになる。
フラグレジスタを1バイト分の一時保存領域として使えるわけだ。
|