我现在开始使用6502程序集,并且在绕过需要处理大于8位的数字的循环时遇到问题。
具体来说,我想循环一些内存位置。在伪c代码中,我想这样做:
// Address is a pointer to memory
int* address = 0x44AD;
for(x = 0; x < 21; x++){
// Move pointer forward 40 bytes
address += 0x28;
// Set memory location to 0x01
&address = 0x01;
}
从地址$44AD
开始,我想将$01
写入ram,然后向前跳转$28
,将$01
写入其中,然后向前跳转$28
再次,直到我完成了20次(写的最后一个地址是$47A5
)。
我目前的方法是循环展开,编写起来很繁琐(尽管我认为汇编程序可以更简单):
ldy #$01
// Start from $44AD for the first row,
// then increase by $28 (40 dec) for the next 20
sty $44AD
sty $44D5
sty $44FD
[...snipped..]
sty $477D
sty $47A5
我知道绝对寻址(使用累加器而不是Y寄存器 - sta $44AD, x
),但这只能给出0到255之间的数字。我真正想要的是这样的:
lda #$01
ldx #$14 // 20 Dec
loop: sta $44AD, x * $28
dex
bne loop
基本上,从最高地址开始,然后循环。问题是$ 14 * $ 28 = $ 320或800 dec,这比我实际存储在8-bit X寄存器中的要多。
有优雅的方法吗?
答案 0 :(得分:8)
6502是一个8位处理器,因此您无法完全在寄存器中计算16位地址。你需要间接通过第0页。
// set $00,$01 to $44AD + 20 * $28 = $47CD
LDA #$CD
STA $00
LDA #$47
STA $01
LDX #20 // Loop 20 times
LDY #0
loop: LDA #$01 // the value to store
STA ($00),Y // store A to the address held in $00,$01
// subtract $28 from $00,$01 (16-bit subtraction)
SEC
LDA $00
SBC #$28
STA $00
LDA $01
SBC #0
STA $01
// do it 19 more times
DEX
BNE loop
或者,您可以使用自修改代码。这是一种可疑的技术,但在6502等嵌入式处理器上很常见,因为它们非常有限。
// set the instruction at "patch" to "STA $47CD"
LDA #$CD
STA patch+1
LDA #$47
STA patch+2
LDX #20 // Loop 20 times
loop: LDA #$01 // the value to store
patch:STA $FFFF
// subtract $28 from the address in "patch"
SEC
LDA patch+1
SBC #$28
STA patch+1
LDA patch+2
SBC #0
STA patch+2
// do it 19 more times
DEX
BNE loop
答案 1 :(得分:2)
复制1k数据的更有效方法:
ldy #0
nextvalue:
lda address, y
sta address, y
lda address+$100, y
sta address+$100, y
lda address+$200, y
sta address+$200, y
lda address+$300, y
sta address+$300, y
iny
bne nextvalue
很少注意到:
更快,因为循环开销减少了。由于更多命令,占用的空间更多。
如果您使用的汇编程序支持宏,您可以轻松地对其进行配置,代码处理的块数。
可能与此没有100%的相关性,但这是另一种长度超过255循环的方法:
nextblock:
ldy #0
nextvalue:
lda address, y
iny
bne nextvalue
;Insert code to be executed between each block here:
dec numblocks
bpl nextblock
numblocks:
.byte 3
很少注意到:
目前,代码并没有真正做任何有意义的事情,而是运行循环“numblocks”次。 “添加你自己的代码”:-)(我常常将它与一些自修改代码一起使用,例如增加sta,y地址)
bpl可能很危险(如果你不知道它是如何工作的),但在这种情况下运行良好(但如果numblocks地址包含足够大的值,则不会)
如果您需要再次执行相同的代码,则需要重新设置numblocks。
通过将numblocks置于零页面可以使代码更快一些。
如果其他东西不需要(通常是这样),你可以使用X寄存器而不是内存位置。