问题描述
我编写了一个小的 6502 程序来循环内存并使用 STA 零页间接寻址将值存储在 128 个连续的内存位置,但该程序似乎无法正常工作。它应该将值 $01 的 128 个副本存储到内存地址 $0400 之后,但它没有。我做错了什么?
*=$8001
; set $00,$01 to $0400
LDA #$00
STA $00
LDA #$04
STA $01
CLC ; Clear carry and decimal mode
CLD
LDX #128 ; Loop 128 times
LDY #0
loop LDA #$01 ; the value to store
STA ($00),Y ; store A to the address held in $00,$01
; Add 1 to $00,$01 (16-bit addition)
LDA $00
ADC #1
STA $00
LDA $01
ADC #0
STA $01
; do it 127 more times
DEX
BNE loop
RTS
解决方法
看起来您正在增加 $00
中存储的值,但您不应该操作 Y
吗?类似的东西:
*=$8001
LDA #$00 ; store $0400 into $00 and $01
STA $00
LDA #$04
STA $01
LDY #128 ; load 128 into Y
LDA #$01 ; load 01 into A
loop DEY
STA ($00),Y ; store A into $0400 + Y
BNE loop ; loop until Y is zero
RTS
在这个循环中,我们去掉 X
,将 Y
初始化为 128,然后每次循环迭代递减 Y
。这意味着我们正在“向后”填充内存。
注意 1
地址 $00
和 $01
通常是特殊的(例如,
在 C64 上,这些地址控制处理器功能),因此取决于
在您的环境中,您可能需要选择不同的零内存
位置。
注意 2
如果我写这个,我会避免将地址直接硬编码到代码中,而是声明一个命名的存储位置。在本地测试您的代码时,我使用 64tass 和以下代码组装它:
*=$00fb
addr .word ? ; declare two bytes of storage at * and *+1
; I'm using $00fb because this is an unused zero
; page location on the c64 (and I'm testing using
; the VICE emulator).
*=$8001
LDA #$00 ; store $0400 into addr and addr+1
STA addr
LDA #$04
STA addr+1
LDY #128
LDA #$01
loop DEY
STA (addr),Y
BNE loop
RTS
更新 1
你的原始代码对我来说似乎很好用。请注意,在 C64 仿真器中进行测试时,范围 $0400-$0480
对应于屏幕内存(参见例如 this memory map),因此当返回 BASIC 时,该范围将被覆盖。例如,在 $8001
加载您的代码后,我会在监视器中看到以下代码(假设我们将地址存储在 $FB
和 $FC
中):
(C:$e5cf) d 8001
.C:8001 A9 00 LDA #$00
.C:8003 85 FB STA $FB
.C:8005 A9 04 LDA #$04
.C:8007 85 FC STA $FC
.C:8009 18 CLC
.C:800a D8 CLD
.C:800b A2 80 LDX #$80
.C:800d A0 00 LDY #$00
.C:800f A9 01 LDA #$01
.C:8011 91 FB STA ($FB),Y
.C:8013 A5 FB LDA $FB
.C:8015 69 01 ADC #$01
.C:8017 85 FB STA $FB
.C:8019 A5 FC LDA $FC
.C:801b 69 00 ADC #$00
.C:801d 85 FC STA $FC
.C:801f CA DEX
.C:8020 D0 ED BNE $800F
.C:8022 60 RTS
如果我在 $8022
处放置一个断点并调整代码...
(C:$8029) break 8022
BREAK: 1 C:$8022 (Stop on exec)
(C:$8029) g 8001
#1 (Stop on exec 8022) 064 011
.C:8022 60 RTS - A:04 X:00 Y:00 SP:f2 ..-...Z. 4131803
然后检查目标内存范围,里面填满了$01
:
(C:$8022) m 400,480
>C:0400 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0410 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0420 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0430 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0440 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0450 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0460 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0470 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
>C:0480 20
但是一旦我回到 BASIC,它看起来像这样:
(C:$e5d4) m 400,480
>C:0400 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0420 20 20 20 20 20 20 20 20 12 05 01 04 19 2e 20 20 ......
>C:0430 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0450 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0460 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0470 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
>C:0480 20