________________________ | | | S−OS講座・第5回「Z80:分岐と繰返し」 | | |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ・橘中之「喜」  昔,巴の国の,ある橘(たちばな)の木に大きい実成れり.主人,取って割るに, 内にパソコンに興じる仙人の姿あり...  だいぶすずしくなった今日このごろ,みなさんいかがお過ごしですか?(この文章 が出るころには,寒くなっているでしょうが)  前回までのプログラムでは,主に計算とデータ転送について学びました.いままで は,アドレスの小さい順に命令を実行していく,直線型のプログラムでしたが,今回 ~~~~~~ はプログラムを繰返し実行する場合(ループ型)と,条件によって命令の実行をスキ ~~~~~~~~ ップしたり(分岐型)する方法について解説します. ~~~~~~ ・PCはプログラムのみちしるべ  Z80では,これから実行しようとする命令のアドレスは,PCレジスタ(プログ ラム・カウンタ)に入っています.命令がCPUに読み込まれると.PCレジスタの 内容は+1されます(2バイト,3バイト命令の場合は,これが2回,3回と繰返さ れる).  例)メモリの8000H番地〜に,つぎのプログラムが入っている場合. アドレス プログラム 0)PCは,最初8000H. +------+------- 1)3EHを読み込んで,PC←PC+1. 8000 3E 2)01Hを読み込んで,PC←PC+1. 8001 01 (この時点でPC=8002H) 8002 21 3)「LD A,1」を実行するから,A←1. 8003 00 4)21Hを読み込んで,PC←PC+1. 8004 80 5)00Hを読み込んで,PC←PC+1. . 6)80Hを読み込んで,PC←PC+1. . (この時点でPC=8005H) . 7)「LD HL,8000H」を実行するから, HL←8000H.  このように,CPUは,常にPCレジスタが指し示すメモリのアドレスから命令を 読み出し(フェッチ)ては,PCレジスタの内容を増加させ,実行してゆきます.し たがってPCレジスタは,プログラムを実行するのに不可欠な,「道しるべ」の役割 を担っていると言えましょう. ・道のりを変更する,JP命令 それでは,PCレジスタの値を強制的に変更して,「道のり」を変えることができ るでしょうか?  PCレジスタの内容を変更して,プログラムの処理の流れを変えるには, 「JP(ジャンプ)命令」 を使用します.つぎのプログラムをご覧ください. 【プログラム】押したキーのコードを16進表示する. ラベル ニモニック コメント -------+-------+----------------+----------------------------------------- _PRTHX EQU 1FC1H ; Aレジの内容を16進表示するサブルーチン _FLGET EQU 2021H ; Aレジに1文字入力するサブルーチン ORG 8000H ; 8000Hより始めよ LOOP: CALL _FLGET ; A←キーコード CALL _PRTHX ; Aの内容を16進表示 JP LOOP ; LOOPへ戻る(PC←LOOP) ~~~~~~~~~~~~~~ ここで,CALL命令は,今のところ「S−OSのサブルーチンを呼び出す」命令 と考えておいてください.  アセンブル,実行してみると,例えばA,B,Cの順に押すと,414243と表 示されます. A>A OBJECT CODE END 8008 A>J8000 414243 ←ABCと押す このプログラムは,最終行の「JP LOOP」によって,PCレジスタにラベルL OOPの示すアドレス(この場合8000H)がセットされ,繰返しLOOPに戻る ので,いつまでたっても終了しません.終わりたいときは,RESETしてください.  ジャンプ命令は,通常アドレスの小さい順に実行されるプログラムの実行先を,別 のアドレスへ変更するという働きがあります.いいかえれば,PCレジスタへアドレ スをロードすることになるので, 「JP LOOP = LD PC,LOOP」 と書けることがおわかりいただけると思います. ・計算結果によってジャンプする(JP cc命令) 先ほどのプログラムでは,プログラムの内部に終了条件が示されていません.つま り,RESETしない限りプログラムを終了させることはできません.そこで,プロ グラム内で条件を判断させる方法が必要となります. 実はJP命令には, 「条件つきでジャンプしたり,しなかったりする」 ための命令があります.一般には 「JP cc命令」 という命令セットが備わっています.プログラムを見てみましょう. 【プログラム】8010H番地〜のメモリに,50H,4FH,4EH...と,80バイト格納する. ラベル ニモニック コメント -------+-------+----------------+------------------------------------------- DATAS EQU 8010H ; データ領域の先頭アドレス ORG 8000H ; 8000Hより始めよ LD HL,DATAS ; HL←データ領域の先頭アドレス LD A,80 ; A←80 LOOP: LD (HL),A ; (HLが指すメモリ)←A INC HL ; HL←HL+1 DEC A ; A←A−1 JP NZ,LOOP ; A≠0ならばLOOPへ戻る RET ; おわり  アセンブル,実行してみると,8010H〜805FHまで,数字が並んでいるこ とと思います. A>A OBJECT CODE END 800C A>J8000 A>D8000 :8000 21 10 80 3E 50 77 3D C2 :8008 05 80 C9 .. .. :8010 50 4F 4E 4D 4C 4B 4A 49 :8018 48 47 46 45 44 43 42 41 : : :8058 08 07 06 05 04 03 02 01 :8060 .. ..  4行目で,Aレジスタに繰返しの回数をセットしています.5行目のLD命令によ り1バイト書き込んで,ポインタのHLレジスタを+1した後,Aレジスタから1を 引きます.この結果がゼロでないなら7行目の ~~~~~~~~~~~~~~ JP NZ,LOOP が働いて,5行目のLD命令(アドレスでいえば,8005H番地)へ戻ります.1 引いた結果がゼロならば,何事も起こらず次の命令(つまり,RET)へ行って終わ ~~~~~~~~~~ ります.  以前,2バイト以上の計算のところで述べたように,Z80には,桁あふれを記憶 しておく「Cフラグ」があります.それと同じように,直前の演算の結果がゼロであ ったかどうかを記憶する 「ゼロフラグ」 があるのです(以降Zフラグと略記します).  DEC命令は,以前述べたINC命令と同様に,桁あふれは記憶しませんが,ゼロ になったかどうかは憶えています.「JR NZ」命令は,このZフラグの内容を見 て,ジャンプしたりしなかったりするわけです.  また,このプログラムのAレジスタのように,繰返しの計算に使用するレジスタを 「カウンタ」 と呼びます. DEC命令とJP NZ命令を組合せることで,数値を降順(大きい者順)に格納 することができました.このように,終了条件が「=0」ならば,くりかえしはJP NZ命令で記述できます.  それでは,終了条件がゼロでない,たとえば昇順(小さい者順)でデータを格納す ることができるでしょうか? つぎのプログラムを見てみましょう. 【プログラム】8010H番地〜のメモリに,00H,01H,02H,...,4FHと80バイト格納する. ラベル ニモニック コメント -------+-------+----------------+----------------------------------------- DATAS EQU 8010H ; データ領域の先頭アドレス ORG 8000H ; 8000Hより始めよ LD HL,DATAS ; HL←データ領域の先頭アドレス LD A,0 ; A←0 LOOP: LD (HL),A ; (HLが指すメモリ)←A INC HL ; HL←HL+1 INC A ; A←A+1 CP 80 ; (Aの内容)<80? JP C,LOOP ; 「<」ならばLOOPへ戻る RET ; おわり  今度は,4行目の「LD A,0」によって,00Hからスタートします.5行目 で,メモリに数値を記憶したあと,HLを+1,Aレジスタも+1します.次の 「CP命令」 によって,Aレジスタと数値80を比較し,Aレジスタのほうが小さければつぎの ~~~~~~~~~~ 「JP C,LOOP」が働いて,ラベルLOOPのLD命令(アドレス8005H) へ戻ります.小さくなければ(つまりこの場合,80になった時ですが)そのまま終 ~~~~~~~~~~~~~~ わりです. ここでCP命令の働きについて述べておきます.CP命令は,Aレジスタと数値を 比較し,Aレジスタのほうが ・小さい(A<n)ならば,Cフラグセット,Zフラグリセット ・等しい(A=n)ならば,Cフラグリセット,Zフラグセット ・大きい(A>n)ならば,Cフラグ,Zフラグ両方リセット という働きがあります.勘のいいかたには察しがつくと思いますが,CP命令は, 「SUB命令の,引き算せずに,フラグ操作のみを行なう命令」 ということができます.  このプログラムに限っては,「JP C」命令の代わりに「JP NZ」命令を用 いても,動作に変わりはありません.なぜなら,直前のCP命令で,Cフラグがリセ ットされるのは,すなわち演算結果がA=80となる時であるからです.  なお,「JP cc」命令のccにあたる条件は,次の種類があります.このうち 用途にもよりますが,Z/NZ,C/NCがよく用いられます.その外の条件の使用 頻度は低いので,急いで覚える必要はないでしょう. cc 読み方 意味 -------+---------------+----------------------------------------- Z ゼロ 演算結果がゼロ,または等しい NZ ノンゼロ 演算結果がゼロでない,または等しくない C キャリー 桁あふれ,または小さい NC ノンキャリ 桁あふれなし,または大きいか等しい P プラス 符号付き数値の時,演算結果がプラス M マイナス 同じく,演算結果がマイナス PE パリティ・イーブン 論理演算で,「1」のビットの数が偶数 PO パリティ・オッド 同じく,奇数 −〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−〜−  次回は,「短いジャンプ,JR命令」と「繰返しに便利なDJNZ命令」について 解説します.それではみなさん,ごきげんよう. (EOF)