loops - 在 6502 上使用零页间接寻址循环内存
问题描述
我编写了一个小型 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 #<$0400 ; store $0400 into $00 and $01
STA $00
LDA #>$0400
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 #<$0400 ; store $0400 into addr and addr+1
STA addr
LDA #>$0400
STA addr+1
LDY #128
LDA #$01
loop DEY
STA (addr),Y
BNE loop
RTS
更新 1
您的原始代码对我来说似乎工作得很好。请注意,在 C64 仿真器中进行测试时,范围$0400-$0480
对应于屏幕内存(参见例如此内存映射),因此当返回 BASIC 时,该范围将被覆盖。例如,当您的代码加载到 时$8001
,我在监视器中看到以下代码(假设我们将地址存储在$FB
and中$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
推荐阅读
- android - Meteor 构建失败:“Android 目标:android:命令失败,退出代码 ENOENT”
- css - 在 react-native 中将阴影应用于容器
- xcode - iOS 12 iPad 拒绝启动请求 - Xcode
- git - 如何获取 ./configure 以生成默认值
- xcode - Xamarin.ios 无法直接部署到物理设备
- entity-framework - 使用带有 ASP.NET 样板的测试框架“努力”时出现问题
- munin - 你如何让 munin 停止发送智能退出状态的警报?
- angular - 使用 Angular 6 在后台进行多个 http 请求
- ionic-framework - 进行构建时在 ionic 中动态设置变量
- angular - 角度复选框需要问题