現在地

続・80系アセンブラのテクニック


カテゴリー:

3回目も昨日に引き続き、80系アセンブラの懐かしいテクニックです。

スタックポインタ(SP)を利用してメモリクリアです。


   1:	8000          	    ORG     8000H
   2:	8000  0600    	    LD      B,0
   3:	8002  110000  	    LD      DE,0000H
   4:	8005  210000  	    LD      HL,0000H
   5:	8008  F3      	    DI
   6:	8009  39      	    ADD     HL,SP
   7:	800A  3100F0  	    LD      SP,0F000H
   8:	800D          	loop:
   9:	800D  D5      	    PUSH    DE
  10:	800E  D5      	    PUSH    DE
  11:	800F  D5      	    PUSH    DE
  12:	8010  D5      	    PUSH    DE
  13:	8011  D5      	    PUSH    DE
  14:	8012  D5      	    PUSH    DE
  15:	8013  D5      	    PUSH    DE
  16:	8014  D5      	    PUSH    DE
  17:	8015  10F6    	    DJNZ    loop
  18:	8017  F9      	    LD      SP,HL
  19:	8018  FB      	    EI
  20:	8019  C9      	    RET

これは0E000H番地から0EFFFH番地までの4KBを0クリアするルーチンです。

割り込み禁止していたり、PUSH命令はあるのにPOP命令がなかったり、単なるメモリクリアにしては怪しいプログラムですね。

2行目でBレジスタを0にしているのはループカウンタです。ループ1回で16バイトなので4KBクリアするには256回ループを回る必要があります。DJNZ命令はBをデクリメントして0でなければ戻ってループする(デクリメント前にチェックはしない)なので、0は256回を意味します。
3行目は書き込む値で、0クリアなので0000Hを入れています。もし0FFHで埋めるのなら0FFFFHになります。
4行目は後で説明します。
5行目は割り込みの禁止です。これ以降、スタックポインタはスタックエリアを指さなくなるので割り込みで戻り番地をスタックに積めなくなるためです。NMI (禁止できない割り込み)が入る可能性がある場合はこのテクニックは使用できません。

6行目は現在のスタックポインタの保存です。本当はLD HL,SPみたいな命令があればよいのですが無い(逆はあります:18行目)ので、4行目で事前にHL ⇐ 0しておいてからHL ⇐ HL+SPを実行しているのです。
7行目でスタックポインタをクリアするエリアの次のアドレスに設定します。
9~16行目で16バイト分のクリアを実行します。PUSH DE命令がSP ⇐ SP-2; (SP) ⇐ DEという動作を利用しています。ループを展開するのは今でも使われるテクニックですよね。ループ回数が256を超えるとDJNZ命令が使えなくなる事情もありこの例では8つ並べていますが、コードが大きくなってもよいなら16にしてループ回数を半分にしてももちろん構いません。

18行目で保存してあったスタックポインタを復元して、19行目で割り込みを許可します。

もしこれを素直に書くと


   9:	800D  D5      	    PUSH    DE

のところが


   9:	800D  77      	    LD      (HL),A
  10:	800E  23      	    INC     HL
  11:	800F  77      	    LD      (HL),A
  12:	8010  23      	    INC     HL

のような形になります。もちろんレジスタの使い方も違うのでほかの部分も書き換えなくてはなりません。
Z80の場合前者は11クロックですが、後者は26クロックもかかるのでクリアするエリアが大きければメリットがあります。
一方、任意のサイズに対応させるのは面倒なのでグラフィックVRAMのクリアのようにサイズが決まっている場合でないと使いにくいですね。

ここに挙げたコード例は記憶を頼りに書いてクロスアセンブルしてリスティングファイルから抜粋しました。実行確認はしていないので間違いが含まれているかもしれません。お気付きの方は「ご意見・ご要望」にてご指摘いただけると助かります。

コメントを追加

Plain text

  • HTMLタグは利用できません。
  • ウェブページアドレスとメールアドレスは、自動的にハイパーリンクに変換されます。
  • 行と段落は自動的に折り返されます。
※ コメントは原則公開です。個別のご相談などは「ご意見・ご要望」からお願いします。