標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第587回]

●整数BASICコンパイラ(SBASIC) FOR〜NEXT

前回、前々回と2回にわたって、100回の加算を行いながら、OUT文を実行して、パルスを出力するプログラムを、Z80アセンブラ(機械語)プログラム、Z80BASIC(インタプリタ)プログラム、SBASIC(コンパイラ)プログラムの3通り書いて、それぞれ実行してその出力パルスをオシロスコープで見てみました。

BASICでは加算命令とIF GOTOとの組み合わせで時間待ちループを作る方法のほかに、FOR NEXT文による方法が考えられます。
そこで今回はFOR NEXT文を使って、パルスを出力してみたいと思います。

まずはZ80BASICです。

前々回([第585回])のプログラムの
B%=B%+1:IF B%<=A% GOTO
のところを
FOR A%=1 TO 100:NEXT A%
に変更しました。

実行結果です。

FOR NEXT文100回のループの実行時間は約20msecです。
[第585回]で100回加算とGOTOを繰り返したプログラムの実行時間は130msecでした。
おお。
大幅に速度アップしました。
プログラムの動作としてはどちらも同じことをやっていても、実行時間は全然異なる結果になりました。
加算プログラムは汎用の計算ルーチンをコールするためにどうしても時間がかかってしまいます。
一方FOR NEXT文は型にはまった動作をすることになりますから、それだけ無駄を省いたプログラムにできるためです。
インタプリタの命令としては、FOR NEXT文の実行時間は「非常に速い」ということが言えると思います。

次はSBASICです。
いつものようにメモ帳(notepad)でソースプログラムを書きました。

'SBASIC TEST3 10/8/19
	ORG=$8004
	OUT $83,$80
*LOOP:OUT $80,0
	FOR A%=1 TO 100:NEXT A%
	OUT $80,1
	FOR A%=1 TO 100:NEXT A%
	GOTO *LOOP

SBASICコンパイラで機械語のバイナリファイルを作成します。
前回と同じように、コンパイルの結果作成されたバイナリファイルsbtest3.binを逆アセンブラZDAS.COMで逆アセンブルしてみました。

逆アセンブルしてできたリストです。

8004 218300         LD HL,$0083
8007 4D             LD C,L
8008 218000         LD HL,$0080
800B ED69           OUT (C),L
800D 218000         LD HL,$0080
8010 4D             LD C,L
8011 210000         LD HL,$0000
8014 ED69           OUT (C),L
8016 AF             XOR A
8017 320BF2         LD ($F20B),A
801A CD5E3E         CALL $3E5E
801D 2140F4         LD HL,$F440
8020 7D             LD A,L
8021 110100         LD DE,$0001
8024 73             LD (HL),E
8025 23             INC HL
8026 72             LD (HL),D
8027 116400         LD DE,$0064
802A 010100         LD BC,$0001
802D 213280         LD HL,$8032
8030 08             EX AF,AF'
8031 D9             EXX
8032 CD613E         CALL $3E61
8035 218000         LD HL,$0080
8038 4D             LD C,L
8039 210100         LD HL,$0001
803C ED69           OUT (C),L
803E CD5E3E         CALL $3E5E
8041 2140F4         LD HL,$F440
8044 7D             LD A,L
8045 110100         LD DE,$0001
8048 73             LD (HL),E
8049 23             INC HL
804A 72             LD (HL),D
804B 116400         LD DE,$0064
804E 010100         LD BC,$0001
8051 215680         LD HL,$8056
8054 08             EX AF,AF'
8055 D9             EXX
8056 CD613E         CALL $3E61
8059 C30D80         JP $800D
805C C9             RET

CALLしているアドレス3E5EはFOR文のサブルーチンです。
3E61はNEXT文のサブルーチンです。

SBASICコンパイラでバイナリファイルとともに作成されたsbtest2.wkファイルです。

0000 'SBASIC TEST3 10/8/19
0000 	ORG=$8004
8004 	OUT $83,$80
800D *LOOP:800D OUT $80,0
8016 	FOR A%=1 TO 100:8032 NEXT A%
8035 	OUT $80,1
803E 	FOR A%=1 TO 100:8056 NEXT A%
8059 	GOTO *LOOP
805C

SBASICコンパイラで作成された、機械語のバイナリファイルは、Z80BASICを起動してから、/LDコマンドでメモリにロードします。


機械語サブルーチンコール命令USR($4004)をダイレクトに実行してもよいのですが、今回はJPコマンドを使いました。

実行結果です。

FOR NEXTループ100回の実行時間は5msecほどという結果になりました。
[第585回]で100回加算とGOTOを繰り返したプログラムの実行時間は約4.4msecでした。
あれ。
SBASICコンパイラでは、逆にFOR NEXTのほうが時間がかかってしまいました。
Z80BASICインタプリタでは加算ルーチンよりもFOR NEXTルーチンのほうが効率良く実行されたのですが、SBASICコンパイラでは加算処理とFOR NEXTの処理の実行時間がそれほど差がないということのために、こういう結果になりました。

今回のFOR NEXT文についてはZ80BASICインタプリタの実行速度が結構速かったために、SBASICコンパイラとの差が縮まってしまいましたが、それでもまだインタプリタに比べて、コンパイラのほうが数倍速い、ということに間違いはありません。
2010.8.19upload

前へ
次へ
ホームページトップへ戻る