问题提出:
本来是想看看,MCS-51在进中断前会不会将psw入栈保存起来,查了下指令集,却发现:
ret
((sp))-->PCH
(sp)-1-->sp
((sp))-->PCL
(sp)-1-->sp
reti
((sp))-->PCH
(sp)-1-->sp
((sp))-->PCL
(sp)-1-->sp
发现reti和ret 做了同样的事情 --- 出栈PC指针,都没有将psw出栈的过程,所以系统在响应中断前,只将程序指针PC保存起来 psw却没有保护起来。
所以,以后在中断服务程序中首先应该把psw保存在栈中或者寄存器中,在中断服务程序结束前,再将psw的值恢复,使正常程序流程不被破坏。
由此引发另外一个问题。ret 和reti在指令集上一致,那么是否可以互相代替使用?
又翻了下书,关于reti 是这样描述的:
这条指令除了完成ret指令的功能以外,还清除内部相应的中断状态寄存器触发器(该触发器不可寻址,由CPU响应中断时置位,指示CPU当前是否在处理高级或低级中断)
猜想:
在非中断过程调用的子程序用ret和reti返回是可以相互替代的。
如果在中断过程中调用的子程序也用reti返回,那么中断状态寄存器触发器会被提前清除,
如果实际上中断过程仍在继续,而这时又有其他中断源来临(即便中断源优先级和此时中断程序的优先级相比低或者相同),系统也会响应新的中断源。
而在中断程序中的返回如果用ret来代替,虽然响应完一次中断后能正常返回,但是中断状态寄存器触发器没有被清除。
那么如果有比其优先级低或者优先级相同的中断请求,MCS-51将不会响应请求。
验证:
---------
待验证。。。。。。额。我真懒。
结论:
-----------
未验证猜想,做开发的话用C语言编译器会做好这个事情,
如果被迫要写汇编的话,那么该用ret 就用ret,该用reti就用reti吧,这不是废话,
简而言之
中断函数返回用reti,
普通函数返回及中断函数中调用的普通函数返回用ret。
|