標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第82回]
●PUSH命令、POP命令のクロック毎の動作の写真を撮ったのですが…
PUSH命令は[第69回]、POP命令は[第70回]で説明しました。
今回はPUSH命令とPOP命令のクロック毎の動作を説明するつもりで、次のプログラムを実行させました。
0000 310080 LXI SP,8000
0003 F5 PUSH PSW
0004 E5 PUSH H
0005 F1 POP PSW
0006 E1 POP H
マシン語のプログラムに慣れた方は、「このプログラムはおかしい」と思われるかもしれません。
確かにこのプログラムは一般的ではありません。
PUSH命令とPOP命令の組み合わせが違っています。
普通は次のようにします。
PUSH PSW
PUSH H
(この間にA、F、H、Lの値を変更してしまうようなプログラムが入るので、それらの値を保存しておくためにPUSH命令を使う)
POP H (保存しておいたHLレジスタの値をもとにもどす)
POP PSW (保存しておいたA、Fレジスタの値をもとにもどす)
最初のプログラムでは、POP PSW命令によって、HLレジスタの値がAレジスタとF(フラグ)レジスタに入り、POP H命令によって、AレジスタとF(フラグ)レジスタの値がHLレジスタに入ってしまいます。
しかし、今回はわざとそのようにしているのです。
後のプログラムのようにすると、PUSHしたあと、すぐに同じレジスタにPOPして値を戻すことになるので、レジスタの中身が書き換わりません。バスの状態を注意深く見れば、PUSH、POPが正しく機能しているかどうかの判断は可能ですが、POP命令によって、もとの値が別のレジスタに書き込まれた方が、その動作がよくわかると思ったからです。
●PUSH、POPはわざと組み合わせを変えることがある
余談になりますが、今回のような特殊な目的以外でも、フラグレジスタについては、わざと最初のようなプログラムを書くことがあります。
F(フラグ)レジスタはその値そのものを見ることはできません。
S(サイン)フラグとかZ(ゼロ)フラグとかというように、フラグビット単独では、条件付JMP命令などで、その状態を確認することができますが、各フラグビットをひとまとめにした、フラグレジスタそのものの値を読み出したり、値を書き換えたりする命令はありません。
しかし、デバッグツールなどでは、フラグレジスタの値を表示したり、フラグレジスタの値を書き換えたりする必要があります。
そのようなときに、最初のプログラムのような「テクニック」が使われます。
フラグレジスタそのものは中身を見ることができませんが、PUSH PSWの次に、POP H(POP B、POP Dでもよい)を実行することによって、フラグレジスタの値がLレジスタ(POP BならCレジスタ、POP DならEレジスタ)に入るので、普通のデータとして表示することができるようになります。
逆に、PUSH Hの次にPOP PSWを実行すれば、Lレジスタの値を、F(フラグ)レジスタに入れることができます。
●スタックの値が変わってしまう?
さて、話をもとに戻します。
PUSH命令とPOP命令をクロックごとに動作させて、写真を撮ったのですが、1箇所おかしいところが出てきてしまいました。
最後のPOP Hを実行させたとき、Lレジスタには、最初にPUSH PSWを実行したときの、F(フラグ)レジスタの値が入るはずなのですが、メモリからはまったく別の値がでてきてしまうのです。
PUSH PSWを実行するときには、まちがいなく、Aレジスタの値とF(フラグ)レジスタの値がメモリに書き込まれるところを、クロック毎の動作をさせて、はっきりと確認しています。
ところがPOP Hを実行してみると、F(フラグ)レジスタの値を書き込んだはずのメモリアドレスからは別の値が読み出されてしまいます。
おかしいと思って、繰り返し試してみても、いつも結果は同じです。
F(フラグ)レジスタの値の代わりにどんな値が読み出されるかというと、不思議なことに、そのすぐ次の命令PUSH HのOPコードである”E5”なのです。
そんなばかなことが…。
ありえない、と思ったのですが、現実におこっているのですから、そこには何か理由があるはずです。
PUSH命令のタイミングチャートを見ているうちに、原因がわかりました。
前にWKレジスタの誤書き込みについて書きました([第72回])。
WKレジスタの値が変わってしまう原因はregWRのタイミングでした。
今回はMEMWRのタイミングに問題がありました。
PUSH命令のタイミングチャート([第69回])です。
このMEMWRのタイミングについては、「大丈夫かなぁ」と思いながら、回路を組んだのですが、やっぱり大丈夫ではありませんでした。
問題はT3のSPclkとT4のMEMWRがくっついているところにありました。
というところで、時間がなくなってしまいました。
この続きは、次回にすることにいたします。
2008.9.29upload
前へ
次へ
ホームページトップへ戻る