想请问一下,中断响应前保护现场,需要保护ACC, DPTR, R0 ,R1,为什么A和DPTR可以直接PUSH进堆栈,通用寄存器R0R1需要mov到A再push呢?
基于Monster 组和GPT的调写:
这种寻址方式是以DPTR或者PC作为基址寄存器,以累加器A作为变址寄存器,并且以两者相加形成的新的16位地址作为目的地址,
采用变址寻址的指令只有三条:
MOVC A, @A+DPTR
MOVC A, @A+PC
JMP @A+DPTR
注意:前两条指令适用于读程序存取器之中固定的数据,例如将固定的,按一定顺序排列的表格参数存放在程序存储器中,在程序运行之中由A中的动态内容来确定读取的表格参数
后一条指令更适合于实现不同程序入口的跳转
根据参考资料和题目要求,可以得出如下解决方案:
首先,需要了解一下堆栈模型。在51单片机中,堆栈采用顶部向下的模式,即入栈是将值存放在当前SP指针指向的地址,然后SP指针向下移动一位,出栈是将当前SP指针所指的值弹出,然后SP指针向上移动一位。
在中断响应前,需要进行现场保护,即将需要保护的寄存器的值入栈保存。对于ACC和DPTR,可以直接使用PUSH指令将它们的值入栈。对于R0和R1,因为它们没有直接对应的入栈指令,需要先将它们的值mov到A寄存器,再进行PUSH操作。
具体实现代码如下:
;现场保护
PRESERVE:
PUSH ACC ;将ACC入栈
MOV A, R0 ;将R0的值mov到A寄存器
PUSH A ;将A的值入栈
MOV A, R1 ;将R1的值mov到A寄存器
PUSH A ;将A的值入栈
PUSH DPL ;将DPL的值入栈
PUSH DPH ;将DPH的值入栈
RETI ;退出中断响应
;现场恢复
RESTORE:
POP DPH ;将DPH的值出栈,恢复原来的值
POP DPL ;将DPL的值出栈,恢复原来的值
POP A ;将A的值出栈,恢复原来的值
MOV R1, A ;将A的值mov到R1寄存器,恢复原来的值
POP A ;将A的值出栈,恢复原来的值
MOV R0, A ;将A的值mov到R0寄存器,恢复原来的值
POP ACC ;将ACC的值出栈,恢复原来的值
RETI ;退出中断响应