可以做到不占用用户堆栈吗?


答:可以,但是实现的方法并不是很好。由于写到断点处的指令必须是一条LCALL的指令,LCALL的指令需要使用两个字节的堆栈。LCALL指令提供16位的目标地址,以调用64K字节范围内所指定的子程序,执行本指令,首先程序计数器PC=PC+3,然后把PC压入堆栈,先压入低8位,再压入高8位,SP=SP+2.然后才跳到要调用的子程序。

为了不占用用户的堆栈,必须先腾出两个字节的堆栈空间,以执行LCALL指令,可以使用SST89C58的特殊寄存器(例如SFAH,SFAL,SFDT,WDTD,这些寄存器可以当作RAM来使用)来临时保存两个字节的堆栈,例如使用SFDT和WDTD,在用户程序的断点处写入以下3条指令:

POP SFDT

POP SFTD

LCALL LF200H

在执行LCALL LF200H指令之前,使用POP指令腾出两个字节的堆栈,这样就可以不占用用户的堆栈,因为堆栈的两个字节已经被监控程序保存好了,没有被覆盖掉。但这样需要在用户的程序断点处写入6个字节的指令,会破坏用户的程序结构,因此我没有使用这种方法。我使用的是占用2个堆栈的方法。2个字节的堆栈占用不多,如果用户连两个字节的可用堆栈都没有,脱离监控程序之后,这样的用户程序在真正运行时是会出问题的。