LDA 命令 (Load Accumulator from Memory)

アキュムレータに対し8ビットないし16ビットの値をロードします。

LDAオーバーロード

オペコード構文アドレッシングモードバイト数命令サイクル注
A9LDA #constImm.2/ 321, 4
A5LDA dpDP.231, 2
B2LDA (dp)DP. Ind251, 2
A7LDA [dp]DP. Ind long261, 2
B5LDA dp, XDP. Idx X241, 2
A1LDA (dp, X)DP. Idx Ind X261, 2
B1LDA (dp), YDP. Ind Idx Y251, 2, 3
B7LDA [dp], YDP. Ind long Idx Y261, 2
ADLDA absAbs.341
BDLDA abs, XAbs. Idx X341, 3
B9LDA abs, YAbs. Idx Y341, 3
AFLDA longAbs. long451
BFLDA long, XAbs. long Idx X451
A3LDA sp, SSR.241
B3LDA (sp, S), YSR. Ind Idx Y271

注

  1. メモリモードフラグクリア時は1サイクル追加
  2. ダイレクトページの開始アドレスがページ境界になっていない場合1サイクル追加
  3. インデクス加算時にページ境界を超える場合、またはインデクスレジスタが16ビット長の場合は1サイクル追加
  4. メモリモードフラグクリア時は3バイト。メモリモードフラグセット時は2バイト。

フラグ変化

n-----z-

n: 読み込んだ値のMSBが格納される。
z: 読み込んだ値が0の場合にセットされ、それ以外の場合はクリアされる。

解説

LDA命令はオペコードによって指定されたアドレッシングモードに従ってアキュムレータに値をロードします。
ステータスレジスタのメモリモードフラグがクリアされている場合は16ビット長のデータをロードし、メモリモードフラグがセットされている場合は8ビット長のデータをロードします。
データの読み込みはリトル・エンディアン方式で行われます。すなわち、バイナリコードでは常に下位バイトが先に配置されます。

使用例

8ビットと16ビットの読み込み

    SEP #$20
    LDA $10         ; $10の1バイトを読み込む
    REP #$20
    LDA $10         ; $10を下位、$11を上位として2バイトを読み込む

テーブルからの読み込み

インデクスレジスタを使うと、表の中のn番目の値を読み込めます。テーブルが別のバンクにある場合は、ロングアドレスを使います。

    ; Xの値の2乗を読み込む(Aは8ビット、Xは16ビット)
    SEP #$20
    REP #$10
    LDX $10
    LDA.l Squares,X
    ...

Squares:
    db $00,$01,$04,$09,$10,$19,$24,$31

16ビットの値のテーブルを引く場合は、インデクスを2倍してから使います。

同じ番地へのいろいろなアクセス

65C816では、同じ番地を何通りものアドレッシングモードで読むことができます。次はすべて、WRAMの$7E:0010を読む例です。どれを使えるかは、そのときのダイレクトページレジスタ(D)・データバンクレジスタ(DB)・インデクスレジスタの値によって決まります。

    LDA $10         ; ダイレクトページ: D=$0000 のとき $00:0010
                    ;   (バンク$00の$0000~$1FFFはWRAM $7E:0000~$1FFF の写し)
    LDA $0010       ; 絶対: DB=$00・$80・$7E のいずれでも $7E:0010 の内容が読める
    LDA.l $7E0010   ; ロング: DB に関係なく $7E:0010
    LDA $00,X       ; ダイレクトページ + X: D=$0000、X=$0010 のとき
    LDA.l $7E0000,X ; ロング + X: X=$0010 のとき
    LDA ($20)       ; 間接: D+$20 にある16ビット値 $0010 をアドレスとし、バンクは DB
    LDA [$20]       ; ロング間接: D+$20 にある24ビット値 $7E0010 をアドレスとする

バイト数とサイクル数はアドレッシングモードごとに異なります。ダイレクトページは2バイトで最も速く、ロングは4バイトで遅くなります。よく使う変数をダイレクトページに置くのはこのためです。

インデクスとバンクの境界

ネイティブモードでは、アドレッシングモードによって、インデクスを足したアドレスがバンクの境界を越えるかどうかが異なります。思わぬ番地を読み書きする原因になりやすいので注意してください。

アドレッシングモード実際のアドレスバンク内のアドレスが$FFFFを越えた場合
dp、dp,X、dp,YD + dp (+ インデクス)バンク$00の中で$0000に戻る
abs,X、abs,YDB:abs + インデクス次のバンクへ繰り上がる
long,Xlong + X次のバンクへ繰り上がる
(dp),YDB:(ポインタ) + Y次のバンクへ繰り上がる
[dp],Y(24ビットポインタ) + Y次のバンクへ繰り上がる
    ; DB=$7E、X=$0020 のとき
    LDA $FFF0,X     ; $7E:FFF0 + $20 = $7F:0010 を読む(バンクが繰り上がる)

    ; D=$0000、X=$0020 のとき
    LDA $F0,X       ; $00:0110 を読む
                    ; ネイティブモードでは、ダイレクトページ + インデクスは256バイトの範囲に収まらない

    ; Aが16ビット、DB=$7E のとき
    LDA $FFFF       ; 下位バイトは $7E:FFFF、上位バイトは $7F:0000 から読む

一方、プログラムカウンタはバンクの境界を越えません。$xx:FFFFの次の命令は、同じバンクの$xx:0000から読まれます。

参照

LDX命令
LDY命令
STA命令
STX命令
STY命令
STZ命令