CMP 命令 (Compare Accumulator and Memory)
アキュムレータとメモリを比較し、結果をステータスフラグへ返します。
CPAはCMPのエイリアスです。
CMPオーバーロード
| オペコード | 構文 | アドレッシングモード | バイト数 | 命令サイクル | 注 |
|---|---|---|---|---|---|
| C9 | CMP #const CPA #const | Imm. | 2/ 3 | 2 | 1, 4 |
| C5 | CMP dp | DP. | 2 | 3 | 1, 2 |
| D2 | CMP (dp) | DP. Ind | 2 | 5 | 1, 2 |
| C7 | CMP [dp] | DP. Ind long | 2 | 6 | 1, 2 |
| D5 | CMP dp, X | DP. Idx X | 2 | 4 | 1, 2 |
| C1 | CMP (dp, X) | DP. Idx Ind X | 2 | 6 | 1, 2 |
| D1 | CMP (dp), Y | DP. Ind Idx Y | 2 | 5 | 1, 2, 3 |
| D7 | CMP [dp], Y | DP. Ind long Idx Y | 2 | 6 | 1, 2 |
| CD | CMP abs | Abs. | 3 | 4 | 1 |
| DD | CMP abs, X | Abs. Idx X | 3 | 4 | 1, 3 |
| D9 | CMP abs, Y | Abs. Idx Y | 3 | 4 | 1, 3 |
| CF | CMP long | Abs. long | 4 | 5 | 1 |
| DF | CMP long, X | Abs. long Idx X | 4 | 5 | 1 |
| C3 | CMP sp, S | SR. | 2 | 4 | 1 |
| D3 | CMP (sp, S), Y | SR. Ind Idx Y | 2 | 7 | 1 |
注
- メモリモードフラグクリア時は1サイクル追加
- ダイレクトページの開始アドレスがページ境界になっていない場合1サイクル追加
- インデクス加算時にページ境界を超える場合、またはインデクスレジスタが16ビット長の場合は1サイクル追加
- メモリモードフラグクリア時は3バイト。メモリモードフラグセット時は2バイト。
フラグ変化
n-----zc
n: 比較結果のMSBがセットされる
z: 比較結果が0の場合にセットされる
c: 比較結果において符号なし借り(桁下がり)が発生しない場合にセットされる (これは内部演算で算術オーバーフローが発生した場合と等価)
解説
CMP命令はオペコードによって指定されたアドレッシングモードに従って、オペランドで指定された値とアキュムレータを比較し、その結果をステータスフラグへ返します。
比較には減算が用いられ、アキュムレータからメモリの値を引きます。この命令によってアキュムレータおよびメモリの状態は変更されません。
結果が0の場合、すなわち、アキュムレータとメモリの値が等しい場合にはZフラグがセットされます。また、借りが発生しない場合、すなわちアキュムレータの値がメモリの値以上である場合はキャリーフラグがセットされます。
使用例
CMP命令は、比較の結果に応じて分岐命令で処理を振り分けるのに使います。符号なしの値の大小は、キャリーフラグを見るBCC・BCSで判定します。
大小による分岐
LDA $10
CMP.b #$40
BCC .less ; A < $40 のとき
BEQ .equal ; A = $40 のとき
; ここに来るのは A > $40 のとき
範囲のチェック
; A が $20~$3F の範囲にあるかを調べる
CMP.b #$20
BCC .out ; $20 より小さい
CMP.b #$40
BCS .out ; $40 以上
; ここに来るのは範囲内のとき
符号付きの値の大小を比べる場合は、キャリーフラグではなくネガティブフラグとオーバーフローフラグを組み合わせて判定する必要があります。