標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第165回]
●SPHL命令とPCHL命令の実行時間
命令の実行時間はタイムチャートを見て、その実行クロック数から、計算により求めることができます。
SPHL命令とPCHL命令については、[第93回]で説明をしています。そこにはタイムチャートもつけてあります。
タイムチャートを見ると、SPHLとPCHLのクロック数はともに8クロックになっています。
1クロックは0.5μsですから、SPHLとPCHLの実行時間は、0.5×8=4μsになります。
なお、8080では、SPHL、PCHLの実行クロック数は5クロックです。
●テストプログラムの実行時間
実行時間の計算の説明をするために、テストプログラムをもう一度再掲いたします。
プログラムの実行時間を計算するのに必要な、各命令の実行時間は、それぞれの命令の後ろに( )で示しました。
単位はμsです。
0000 3E00 MVI A,00
0002 47 MOV B,A
0003 4F MOV C,A
0004 57 MOV D,A
0005 5F MOV E,A
0006 210001 LXI H,0100
0009 F9 SPHL (4)
000A E9 PCHL (4)
00FE 00 DB 00
00FF 00 DB 00
0100 3B DCX SP (6)
0101 3B DCX SP (4)
0102 F1 POP PSW (4)
0103 3C INR A (4)
0104 F5 PUSH PSW (4)
0105 C20901 JNZ 0109 (6)or(4)
0108 03 INX B (4)or(6)
0109 24 INR H (4)
010A E5 PUSH H (4)
010B 210900 LXI H,0009 (4)
010E E3 XTHL (8)
010F C9 RET (4)
01FE 00 DB 00
01FF 00 DB 00
0200 3B DCX SP (6)
0201 3B DCX SP (4)
0202 F1 POP PSW (4)
0203 3C INR A (4)
0204 F5 PUSH PSW (4)
0205 C20902 JNZ 0209 (6)or(4)
0208 13 INX D (4)or(6)
0209 25 DCR H (4)
020A C30A01 JMP 010A (6)
INX B、INX D、DCX SPの実行時間は4μsと6μsの2通りあります。
INX命令、DCX命令の実行時間については、[第161回]で説明しましたが、もう一度説明しておきましょう。
INX命令は16ビットのレジスタを、+1(インクリメント)するのに、8ビットのカウンタを利用して、下位8ビットと上位8ビットの2回に分けて計算を行います。
まず下位8ビットを+1して、その結果、上位8ビットへの繰り上がりが発生しなければ、そこで計算を打ち切ります。
そのため、繰り上がりがあるときとないときとで、実行時間が異なってきます。
繰り上がりがないときは8クロック(4μs)で、繰り上がりがあるときは12クロック(6μs)です。
DCXは、上位桁からの繰り下がりがないときは8クロック(4μs)で、繰り下がりがあるときは12クロック(6μs)です。
DCX SPの実行時間は、2回続けて実行しているうちの、前の方が6μsで後の方が4μsになっています。
このプログラムの場合は、最初のDCX SPは、0100−1=00FFか、0200−1=01FFのいずれかなので、必ず上位8ビットからの繰り下がりがあります。ですから実行時間は6μsです。
後ろのDCX SPは、00FF−1=00FEか01FF−1=01FEのいずれかなので、実行時間は4μsです。
JNZも2通りの実行時間があります。
条件が成立するとき(notZ、つまりZフラグが立っていないとき)は、指定アドレスにジャンプするために余分な時間がかかりますから6μsで、条件が成立しないとき(Zフラグが立っているとき)は、ジャンプしないで、そのまま次の命令に行きます。このときの実行時間は4μsです。
以上のことを頭に入れておいたうえで、( )の数値をもとにして、プログラムの実行時間を計算してみましょう。
まずは、少し気になる、0105〜0108のJNZ 0109とINX B、それと0205〜0208のJNZ 0209とINX Dについて、検討をしてみます。
0105〜0108のプログラムと0205〜0208のプログラムでは、レジスタが違っているだけで、動作は同じですから、0105〜0108の命令について考えてみます。
INR Aの実行によって、Aレジスタは毎回+1(インクリメント)されます。
実行の結果、Aレジスタが256カウントに1回、00になったとき、JNZ命令がパスされて、INX Bが1回実行されます。
残りの255回は、JNZ命令の条件が成立するため、INX B命令がパスされます。
Aレジスタが256カウントされるときの、0105〜0108の実行時間を計算してみます。
256回に1回、A=00になるときは、JNZはパスされるので実行時間は4μs、そしてINX Bが実行されるので、実行時間は4μs(ここはとりあえず4μsにしておきます)。合計8μs。
その他の255回は、JNZの実行により6μsで、INX Bはパスされるので0μs。
つまり、この部分は256回のうち、255回は6μsで、1回は8μsということになります(INX Bも256回に1回、+2μsになりますが、それについては、あとで考えることにします)。
そのほかの命令の実行時間は一通りだけで変わりません。
それでは、Aレジスタが+1(インクリメント)されるときの、実行時間を求めてみることにします。
0009〜010Fの命令が1回実行されますから、その合計を計算します。
0105〜0108については、6μsで計算します。
4+4+6+4+4+4+4+6+4+4+4+8+4=60μsになります。
ところで、0100〜と0200〜のプログラムは交互に実行されます。
実は、0200〜の実行時間は、020AのJMP命令によって、010Aにジャンプするため、0100〜の実行時間とは少しだけ差があります。
そこで、0200〜についても実行時間を求めてみます(こちらも、0009から始まります)。
4+4+6+4+4+4+4+6+4+6+4+4+8+4=66μsになります。
「BCA」レジスタを+1するプログラム部分と「DEA」レジスタを+1するプログラム部分は交互に実行されますから、その実行時間を合計して、それぞれ1回ずつ実行されるときの時間、ということにします。60+66=126μsです。
これがAレジスタが+1されるのにかかる時間です。
これをもとにして、BCレジスタとDEレジスタが+1される時間を計算します。
Aレジスタが256カウントしたときに、BCレジスタとDEレジスタが+1されますから、その実行時間は、
126×256+2×2=32260μsになります。
+2×2の部分は、先に説明した、256回に1回、INX B(INX D)が実行されるときの、その他の255回に比べて余分にかかる時間です。交互に1回ずつの合計ですから、その2倍です。
32.26msごとにCレジスタ(Eレジスタ)が+1されますが、その様子をLEDの表示で確認しようとしても、下位ビットは速すぎて、ちょっと確認は無理でしょう。
ですから、さらにその上位のBレジスタ(Dレジスタ)が+1される時間も求めてみます。
Cレジスタ(Eレジスタ)が256カウントされるごとにBレジスタ(Dレジスタ)が+1されるのですから、その実行時間は、
32.260×256+0.002×2=8258.564msになります。
+0.002×2は、Bレジスタ(Dレジスタ)が+1されるときは、Cレジスタ(Eレジスタ)からの繰り上がりが発生しているわけですから、そのときのINX命令で余計にかかる2μsです。交互に1回ずつの合計ですから、その2倍です。
●テストプログラムを実行中の写真です
上の列のLEDは、左から、D、E、B、C、Aレジスタで、下の列のLEDは、左から、H、L、SPH、SPLレジスタです。
DEレジスタとBCレジスタはB20Fを表示しています。Aレジスタは速すぎて全点灯しているようにしか見えません。
EレジスタとCレジスタも、最下位ビットの点滅速度は約0.03秒ですから、これも点滅を目視することはできません。
はっきりしているのは、上4ビットは点灯していません、というくらいのことです。
下4ビットが全点灯で0Fですから、Eレジスタ(Cレジスタ)はその半分の08ぐらいにしておきましょう。
Dレジスタ(Bレジスタ)はB2ですから、十進数に直すと、178です。
先ほどの計算から、Dレジスタ(Bレジスタ)が+1されるのには、8.259秒かかりますから、Dレジスタ(Bレジスタ)が178カウントするまでには、
8.259×178=1470.102秒、経過している、ということになります。
Eレジスタ(Cレジスタ)の分は、0.032×8=0.256秒とわずかですから誤差の範囲ですが、一応上の結果に加算しておくことにします。
1470.102+0.256=1470.358秒になります。
ストップウォッチの表示は24’30”です。
秒に直すと、
24×60+30=1470秒です。
おお。今回も一致しましたね。
●もう一枚、写真を撮りました
さきほどより、25分ほど経ってから、もう一枚写真を撮りました
DEレジスタとBCレジスタは640Fを表示しています。
さきほどよりも小さい値になっています。カウンタが一回りしてしまったようです。
Dレジスタ(Bレジスタ)が一回りするのにかかる時間は、
8.259×256=2114.304秒です。
ストップウォッチの表示は、49’00”です。
秒に直すと、2940秒ですから、確かに一回りしています。
念のために計算してみましょう。
Dレジスタ(Bレジスタ)の現在の表示は64です。
十進数に直すと100になりますが、一回りしていますから、100+256=356カウントしていることになります。
経過時間は、
8.259×356=2940.204秒
これに、さきほどと同じように、Eレジスタ(Cレジスタ)の0.256秒を加えることにします。
2940.204+0.256=2940.460秒です。
ストップウォッチの表示と計算結果は一致しました。
2009.2.18upload
前へ
次へ
ホームページトップへ戻る