首页 > 解决方案 > 将内存地址传递给C64程序集中的子程序?

问题描述

param word 0

function
    ...
    lda param,x


scr1 byte "some text"
     byte 0

那么如何将“scr1”传递给“param”呢?我知道这是一个内存地址,所以它不适合 1 字节的寄存器。最好的方法是什么?

编辑:

感谢您的回答!下面发布的解决方案效果很好,但这同时使用了 X 和 Y 寄存器。如果“函数”调用依赖于 X 或 Y 的 KERNAL 例程,或者我自己的代码需要 X 来完成某些事情,该怎么办?在这种情况下,我猜这不会按预期工作?

我对汇编程序完全陌生,所以我对很多事情感到困惑。

基本上我想传递地址,因为我想避免代码重复。我有一个简单的函数,可以像这样在屏幕上打印一个字符串:

        ldx #$00
copy_text
        lda scr1,x
        beq done
        sta screen_start,x
        inx
        bne copy_text
done
        rts

但这仅适用于 scr1。如果想打印其他东西,我需要复制似乎很浪费的代码。

这在汇编程序中可以接受吗?我的意思是,在 C 或任何其他语言中,您只需编写一个可重用的函数或方法。但是在汇编程序中这似乎很难做到,因为只有 3 个寄存器,它们被很多东西使用。

克服此限制的最佳方法是什么?

标签: assemblyparameter-passingcalling-convention6502c64

解决方案


有几种方法可以做到这一点。

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 #$00
   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 #$00
   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 上的机器语言本身只有三个寄存器,因此您的选择通常是在这些寄存器中传递值,或者使用这些寄存器指向更大的数据集,然后您可以在其他地方访问这些数据。在这方面,间接零页是您最好的朋友,因为您可以将指针存储在零页中,然后间接访问它们。


推荐阅读