我是汇编程序的新手,所以这里有一个简单的问题:
我的自定义子程序更改X
,Y
和A
寄存器。他们操纵这些来产生想要的结果。在例程开始时将这些值推入堆栈并在RTS
之前恢复它们是一个好主意吗?
我的意思是,这样我就可以编写可以从任何地方调用的例程,而不会弄乱"状态";或者影响到其他的日常活动。但是这样使用堆栈是可以的吗?还是有更好的方法?
但是这样使用堆栈是可以的吗?还是有更好的方法?
绝对;BASIC总是这样做,内核中的许多例程也是如此。
但是,没有正确的答案,它至少归结为速度,可移植性和风格。
-
如果你经常使用堆栈,有一些速度方面的考虑。开始时典型的
pha
txa
pha
tya
pha
,然后反过来(pla
tay
pla
tax
pla
)消耗了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
各一个),但这是有代价的(不是一个快速的例程)。因为我们正在使用SEI
和CLI
,如果从中断处理程序中执行,您可能需要重新考虑这一点。但这也保持了"真实"。堆栈干净,可用空间增加三倍以上。