Embedded-systems-es-instructions
組み込みシステム-手順
プログラムのフローは、コントロール転送命令が実行されない限り、1つの命令から次の命令へと順次進みます。 アセンブリ言語のさまざまな種類のコントロール転送命令には、条件付きまたは無条件のジャンプと呼び出し命令が含まれます。
ループおよびジャンプ命令
8051でのループ
命令のシーケンスを特定の回数繰り返すことを*ループ*と呼びます。 命令 DJNZ reg、label は、ループ操作を実行するために使用されます。 この命令では、レジスタは1ずつ減少します。ゼロでない場合、8051はラベルが参照するターゲットアドレスにジャンプします。
レジスタには、ループの開始前の繰り返し回数のカウンターがロードされます。 この命令では、レジスタのデクリメントとジャンプの決定の両方が単一の命令に結合されます。 レジスタはR0〜R7のいずれかです。 カウンターはRAMの場所にすることもできます。
例
繰り返し加算の手法を使用して25を10倍します。
解決策-乗数と同じ回数だけ被乗数を繰り返し追加することで、乗算を実現できます。 例えば、
25 * 10 = 250(FAH)
25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 = 250
MOV A,#0 ;A = 0,clean ACC
MOV R2,#10 ; the multiplier is replaced in R2
Add A,#25 ;add the multiplicand to the ACC
AGAIN:DJNZ R2,
AGAIN:repeat until R2 = 0 (10 times)
MOV R5 , A ;save A in R5 ;R5 (FAH)
- 8051の欠点*-命令* DJNZ Regラベル*によるループアクションは、256回の反復のみに制限されています。 条件付きジャンプが行われない場合、ジャンプに続く命令が実行されます。
ループ内のループ
ループを別のループ内で使用する場合、「ネストされたループ」と呼ばれます。 最大カウントが256に制限されている場合、2つのレジスタを使用してカウントを保持します。 したがって、このメソッドを使用して、アクションを256回以上繰り返します。
例
にプログラムを書く-
- 値55Hのアキュムレーターをロードします。
- ACCを700回補完します。
解決策-700は255(レジスタの最大容量)より大きいため、2つのレジスタを使用してカウントを保持します。 次のコードは、カウントに2つのレジスターR2とR3を使用する方法を示しています。
MOV A,#55H ;A = 55H
NEXT: MOV R3,#10 ;R3 the outer loop counter
AGAIN:MOV R2,#70 ;R2 the inner loop counter
CPL A ;complement
その他の条件付きジャンプ
次の表は、8051で使用される条件付きジャンプの一覧です-
Instruction | Action |
---|---|
JZ | Jump if A = 0 |
JNZ | Jump if A ≠ 0 |
DJNZ | Decrement and Jump if register ≠ 0 |
CJNE A, data | Jump if A ≠ data |
CJNE reg, #data | Jump if byte ≠ data |
JC | Jump if CY = 1 |
JNC | Jump if CY ≠ 1 |
JB | Jump if bit = 1 |
JNB | Jump if bit = 0 |
JBC | Jump if bit = 1 and clear bit |
- * JZ(A = 0の場合ジャンプ)*-この命令では、アキュムレータの内容がチェックされます。 ゼロの場合、8051はターゲットアドレスにジャンプします。 JZ命令はアキュムレータにのみ使用でき、他のレジスタには適用されません。
- * JNZ(Aが0に等しくない場合にジャンプ)*-この命令では、アキュムレータの内容がゼロ以外であることがチェックされます。 ゼロでない場合、8051はターゲットアドレスにジャンプします。
- * JNC(キャリーがない場合はジャンプ、CY = 0の場合はジャンプ)*-フラグ(またはPSW)レジスタのキャリーフラグビットを使用して、「JNCラベル」をジャンプするかどうかを決定します。 CPUはキャリーフラグを調べて、キャリーフラグが発生しているかどうかを確認します(CY = 1)。 発生しない場合、CPUはラベルのアドレスから命令のフェッチと実行を開始します。 CY = 1の場合、ジャンプしませんが、JNCの下の次の命令を実行します。
- * JC(キャリーの場合ジャンプ、CY = 1の場合ジャンプ)*-CY = 1の場合、ターゲットアドレスにジャンプします。
- * JB(ビットが高い場合ジャンプ)*
- * JNB(ビットが低い場合にジャンプ)*
注-すべての条件付きジャンプはショートジャンプであることに注意する必要があります。つまり、ターゲットのアドレスはプログラムカウンターの内容の-128〜+127バイト以内でなければなりません。
無条件ジャンプ命令
8051には2つの無条件ジャンプがあります-
- * LJMP(ロングジャンプ)*-LJMPは3バイトの命令で、最初のバイトはオペコードを表し、2番目と3番目のバイトはターゲット位置の16ビットアドレスを表します。 2バイトのターゲットアドレスは、0000からFFFFHまでの任意のメモリ位置へのジャンプを許可するためのものです。
- * SJMP(ショートジャンプ)*-最初のバイトがオペコードで、2番目のバイトがターゲットロケーションの相対アドレスである2バイトの命令です。 相対アドレスの範囲は00HからFFHで、前方ジャンプと後方ジャンプに分かれています。つまり、現在のPC(プログラムカウンター)のアドレスに対して-128〜+127バイトのメモリ内です。 順方向ジャンプの場合、ターゲットアドレスは現在のPCから127バイトのスペース内にあります。 後方ジャンプの場合、ターゲットアドレスは現在のPCから-128バイト以内になります。
ショートジャンプアドレスの計算
すべての条件付きジャンプ(JNC、JZ、およびDJNZ)は2バイトの命令であるため、短いジャンプです。 これらの命令では、最初のバイトはオペコードを表し、2番目のバイトは相対アドレスを表します。 ターゲットアドレスは、常にプログラムカウンターの値に対して相対的です。 ターゲットアドレスを計算するために、ジャンプのすぐ下の命令のPCに2バイト目が追加されます。 以下に示すプログラムを見てください-
Line PC Op-code Mnemonic Operand
1 0000 ORG 0000
2 0000 7800 MOV R0,#003
3 0002 7455 MOV A,#55H0
4 0004 6003 JZ NEXT
5 0006 08 INC R0
6 0007 04 AGAIN: INC A
7 0008 04 INC A
8 0009 2477 NEXT: ADD A, #77h
9 000B 5005 JNC OVER
10 000D E4 CLR A
11 000E F8 MOV R0, A
12 000F F9 MOV R1, A
13 0010 FA MOV R2, A
14 0011 FB MOV R3, A
15 0012 2B OVER: ADD A, R3
16 0013 50F2 JNC AGAIN
17 0015 80FE HERE: SJMP HERE
18 0017 END
後方ジャンプターゲットアドレスの計算
順方向ジャンプの場合、変位値は0から127(16進数で00から7F)の間の正数です。 ただし、後方ジャンプの場合、変位は0〜-128の負の値です。
CALL命令
CALLは、サブルーチンまたはメソッドを呼び出すために使用されます。 サブルーチンは、頻繁に実行する必要がある操作またはタスクを実行するために使用されます。 これにより、プログラムがより構造化され、メモリスペースが節約されます。 LCALLとACALLの2つの命令があります。
LCALL(ロングコール)
LCALLは3バイトの命令で、最初のバイトはオペコードを表し、2番目と3番目のバイトはターゲットサブルーチンのアドレスを提供するために使用されます。 LCALLを使用して、8051の64Kバイトのアドレス空間内で利用可能なサブルーチンを呼び出すことができます。
呼び出されたサブルーチンの実行後にポイントに正常に戻るために、CPUは命令のアドレスをスタックのLCALLのすぐ下に保存します。 したがって、サブルーチンが呼び出されると、制御はそのサブルーチンに移り、プロセッサはPC(プログラムカウンター)をスタックに保存し、新しい場所から命令をフェッチし始めます。 RET(リターン)命令は、サブルーチンの実行を終了した後、制御を呼び出し元に戻します。 すべてのサブルーチンは、最後の命令としてRETを使用します。
ACALL(絶対呼び出し)
ACALLは3バイトのLCALLとは対照的に、2バイトの命令です。 2バイトの11ビットのみがアドレスに使用されるため、サブルーチンのターゲットアドレスは2Kバイト以内でなければなりません。 ACALLとLCALLの違いは、LCALLのターゲットアドレスは8051の64Kバイトのアドレス空間内であればどこでもかまいませんが、CALLのターゲットアドレスは2Kバイトの範囲内にあるということです。