【ジャンプ命令】
プログラムの流れを強制的に変更する命令で、GOTO k、CALL k、RETURN、
RETFIE、RETLW k、がこれに属します。いずれも構造は図2(c)です。
nemonic : 内容 :Flag :Cycle :オペコード
---------------------------------------------------------------------
GOTO k : k -> PC<10:0> : None : 2 : 10 1kkk kkkk kkkk
PCLATH<4:3> -> PC<12:11>
【GOTO命令の動作】
最も基本的なジャンプ命令であるGOTO命令のときの動作は、至って
簡単で、図1で説明します。
(1)命令のフェッチ
プログラムカウンタでアドレスされたプログラムメモリ内の命令が、
命令レジスタに呼び出されます。
(2)命令の解読
命令レジスタに行くと、命令コードが解読され命令の動作が実行
されます。
(3)命令の定数の書きこみ
この命令が命令レジスタに行くと、定数kがALUを通過してデータバス
経由、プログラムカウンタの下位8ビットに上書きされます。
結果として、次ぎに実行されるプログラムの番地が書き換わったことに
なり、プログラムカウンタの示す新しいアドレスにプログラムがジャンプ
することになります。
【ジャンプ命令の種類】
ジャンプ命令の中でも、サブルーチンを作るための命令があります。
それがCALLとRETURN命令で下記のような種類があります。
nemonic : 内容 :Flag :Cycle :オペコード
---------------------------------------------------------------------
CALL adr : Subroutine Call : None : 2 : 10 0kkk kkkk kkkk
PC+1 -> TOS k -> PC<10:0> PCLATH<4:3> -> PC<12:11>
RETFIE : 割り込み処理から : None : 2 : 00 0000 0000 1001
のリターン TOS -> PC, 1 -> GIE(INTCON<7>)
RETLW k : k -> w して : None : 2 : 11 01xx kkkk kkkk
リターン TOS -> PC
RETURN : サブルーチン : None : 2 : 00 0000 0000 1000
からのリターン TOS -> PC
命令構造は、いずれも上の図2(c)の形式です。
【CALL命令の動作】
同じジャンプ命令の中でも、CALL命令は少し複雑な動作をします。
ここでは、スタックメモリが重要な働きをします。
図3でその動作を説明します。
(1)命令のフェッチ
プログラムカウンタでアドレスされたプログラムメモリ内の命令が、
命令レジスタに呼び出されます。
(2)命令の解読
命令レジスタに行くと、命令コードが解読され命令の動作が実行
されます。
(3)スタックへ保存
CALL命令のある次ぎのアドレスをスタックメモリというメモリに保存して
おきます。この時保存されるアドレスは、13ビット長の全部が書き込まれ
保存されます。
(4)定数kの書きこみ
命令レジスタからは、定数kがALUを通過してデータバス経由、プログラム
カウンタの下位8ビットに上書きされます。
結果として、次ぎに実行されるプログラムの番地が書き換わったことに
なり、プログラムカウンタの示す新しいアドレスにプログラムがジャンプ
することになります。
【RETURN命令の動作】
次ぎはRETURN命令の動作ですが、図4で説明します。
(1)命令のフェッチ
プログラムカウンタでアドレスされたプログラムメモリ内の命令が、
命令レジスタに呼び出されます。
(2)命令の解読
命令レジスタに行くと、命令コードが解読され命令の動作が実行
されます。
(3)スタックからの取りだし
スタックメモリにあるアドレスをプログラムカウンタにそのまま移動
コピーします。
結果、スタックにあったアドレスは、CALL命令の次ぎの命令を指して
いるため、CALL命令の次ぎの位置に戻ることになります。
これがサブルーチンと呼ばれるプログラムを実現する手段となって
います。
(4)RETURN類似命令の動作
RETFIE命令はRETURN命令と同じ動作と同時に、割り込みを許可
して戻ります。
RETLW命令はRETURN命令と同じ動作とともに、定数kをWregに
コピーして戻ります。
サブルーチンとは、プログラムの中で何度も同じ処理を繰り返し使う
必要があるとき、毎回同じプログラムを何度も書いていては、プログ
ラムメモリを余分に使うことになり無駄が多く発生してしまいます。
そこでこの繰り返し部分だけを取りだし、独立のサブプログラムと
しておき、使うときにはCALL命令でジャンプし、RETURN命令で戻る
ようにすれば、1個のプログラムをどこからでも使えることになり、1個
だけ、そのサブルーチンを作れば良いことになり効率的なプログラム
とすることが出来ます。
【サブルーチンの例】
BCDからセグメントへの変換サブルーチン(RETLWの使用例)
BCD10進数をセグメントデータに変換する。
セグメントデータはPORTB1〜PORTB7用になっている。
つまり0ビット目は使わない
GET_7SEG
ANDLW 0FH ;下位4ビットのみ取り出し
ADDWF PCL,F ;PCレジスタに数字を加えてジャンプ
RETLW B'01111110' ;Code 0
RETLW B'00001100' ;Code 1
RETLW B'10110110' ;Code 2 ここのデータを持って
RETLW B'10011110' ;Code 3 リターン
RETLW B'11001100' ;Code 4
RETLW B'11011010' ;Code 5
RETLW B'11111010' ;Code 6
RETLW B'00001110' ;Code 7
RETLW B'11111110' ;Code 8
RETLW B'11001110' ;Code 9