将内存地址传递给 C64 汇编中的子程序?
Passing memory address to subroutine in C64 Assembly?
param word 0
function
...
lda param,x
scr1 byte "some text"
byte 0
那么如何将“scr1”传递给“param”呢?我知道这是一个内存地址,所以它不适合 1 字节寄存器。执行此操作的最佳方法是什么?
编辑:
感谢您的回答!下面发布的解决方案效果很好,但这同时使用了 X 和 Y 寄存器。如果“函数”调用依赖于 X 或 Y 或我自己的代码需要 X 的 KERNAL 例程怎么办?在这些情况下,我猜这不会像预期的那样工作?
我对汇编程序完全陌生,所以我对很多事情感到困惑。
基本上我想传递地址,因为我想避免代码重复。我有一个简单的函数,可以像这样在屏幕上打印一个字符串:
ldx #[=11=]
copy_text
lda scr1,x
beq done
sta screen_start,x
inx
bne copy_text
done
rts
但这只适用于 scr1。如果想打印其他东西,我需要复制看起来很浪费的代码。
汇编程序可以接受吗?我的意思是,在 C 或任何其他语言中,您只需编写一个可重用的函数或方法。但是在汇编器中这似乎很难做到,因为只有 3 个寄存器而且它们被很多东西使用。
克服此限制的最佳方法是什么?
有几种方法可以做到这一点。
zpb = $fb
function = *
stx zpb+0
sty zpb+1 ; note after you've stored .X and .Y in zero page they can be re-used for other purposes.
...
ldy #[=10=]
lda (zpb),y
...
caller = *
ldx #<scr1
ldy #>scr1
jsr function
或者你可以玩堆栈
zpb = $fb
function = *
pla ; save current stack pointers for later
sta temp+0
pla
sta temp+1
pla ; pull low byte off first
sta zpb+0
pla ; now pull off high byte
sta zpb+1
lda temp+1 ; restore stack pointers so RTS works as expected
pha
lda temp+0
pha
...
ldy #[=11=]
lda (zpb),y
...
temp .byte 0,0
caller = *
lda #>scr1 ; note we push high byte first since stack is FILO
pha
lda #<scr1
pha
jsr function
6502 本身的机器语言只有三个寄存器,因此您的选择通常是在这些寄存器中传递值,或,使用这些寄存器指向一个您可以在其他地方访问的更大的数据集。在这方面,间接零页是你最好的朋友,因为你可以在零页中存储指针,然后间接访问它们。
param word 0
function
...
lda param,x
scr1 byte "some text"
byte 0
那么如何将“scr1”传递给“param”呢?我知道这是一个内存地址,所以它不适合 1 字节寄存器。执行此操作的最佳方法是什么?
编辑:
感谢您的回答!下面发布的解决方案效果很好,但这同时使用了 X 和 Y 寄存器。如果“函数”调用依赖于 X 或 Y 或我自己的代码需要 X 的 KERNAL 例程怎么办?在这些情况下,我猜这不会像预期的那样工作?
我对汇编程序完全陌生,所以我对很多事情感到困惑。
基本上我想传递地址,因为我想避免代码重复。我有一个简单的函数,可以像这样在屏幕上打印一个字符串:
ldx #[=11=]
copy_text
lda scr1,x
beq done
sta screen_start,x
inx
bne copy_text
done
rts
但这只适用于 scr1。如果想打印其他东西,我需要复制看起来很浪费的代码。
汇编程序可以接受吗?我的意思是,在 C 或任何其他语言中,您只需编写一个可重用的函数或方法。但是在汇编器中这似乎很难做到,因为只有 3 个寄存器而且它们被很多东西使用。
克服此限制的最佳方法是什么?
有几种方法可以做到这一点。
zpb = $fb
function = *
stx zpb+0
sty zpb+1 ; note after you've stored .X and .Y in zero page they can be re-used for other purposes.
...
ldy #[=10=]
lda (zpb),y
...
caller = *
ldx #<scr1
ldy #>scr1
jsr function
或者你可以玩堆栈
zpb = $fb
function = *
pla ; save current stack pointers for later
sta temp+0
pla
sta temp+1
pla ; pull low byte off first
sta zpb+0
pla ; now pull off high byte
sta zpb+1
lda temp+1 ; restore stack pointers so RTS works as expected
pha
lda temp+0
pha
...
ldy #[=11=]
lda (zpb),y
...
temp .byte 0,0
caller = *
lda #>scr1 ; note we push high byte first since stack is FILO
pha
lda #<scr1
pha
jsr function
6502 本身的机器语言只有三个寄存器,因此您的选择通常是在这些寄存器中传递值,或,使用这些寄存器指向一个您可以在其他地方访问的更大的数据集。在这方面,间接零页是你最好的朋友,因为你可以在零页中存储指针,然后间接访问它们。