在6502汇编程序中编写子程序的最佳方式?



我是汇编程序的新手,所以这里有一个简单的问题:

我的自定义子程序更改X,YA寄存器。他们操纵这些来产生想要的结果。在例程开始时将这些值推入堆栈并在RTS之前恢复它们是一个好主意吗?

我的意思是,这样我就可以编写可以从任何地方调用的例程,而不会弄乱"状态";或者影响到其他的日常活动。但是这样使用堆栈是可以的吗?还是有更好的方法?

但是这样使用堆栈是可以的吗?还是有更好的方法?

绝对;BASIC总是这样做,内核中的许多例程也是如此。

但是,没有正确的答案,它至少归结为速度,可移植性和风格。

  • 如果你经常使用堆栈,有一些速度方面的考虑。开始时典型的phatxaphatyapha,然后反过来(platayplataxpla)消耗了3字节的堆栈,并且由于2 x 5操作而增加了一些周期时间

  • 你可以使用零页,但这会减少不同机器之间的可移植性;VIC-20, C64, C128,自由零页地址可能不相同的跨平台。你的例程不能被"多次"调用。没有退出(如没有递归),因为如果它被称为虽然是活跃的,它与新值将覆盖零页面。但是,你不需要使用zero page…

  • …因为你可以在代码中创建自己的内存位置:

    myroutine = *
    ; do some stuff..
    rts
    mymem =*
    .byt 0, 0, 0
    
  • 这样做的缺点是你的例程只能被调用一次,否则后续调用将覆盖你的存储区域(例如不允许递归!!)

  • 你可以写你自己的小栈

    put_registers =*
    sei ; turn off interrupts so we make this atomic
    sty temp
    ldy index
    sta a_reg,y
    stx x_reg,y
    lda temp
    sta y_reg,y
    inc index
    cli
    rts
    get_registers =*
    sei ; turn off interrupts so we make this atomic
    dec index
    ldy index
    lda y_reg,y
    sta temp
    lda a_reg,y
    ldx x_reg,y
    ldy temp
    cli
    rts
    a_reg .buf 256
    x_reg .buf 256
    y_reg .buf 256
    index .byt 0
    temp  .byt 0
    
  • 这有一个额外的好处,你现在有3个虚拟堆栈(.A,.X,.Y各一个),但这是有代价的(不是一个快速的例程)。因为我们正在使用SEICLI,如果从中断处理程序中执行,您可能需要重新考虑这一点。但这也保持了"真实"。堆栈干净,可用空间增加三倍以上。

最新更新