yzwzfyz 发表于 2019-3-8 11:50 他是我师傅 |
楼上是高手,说的是。 如果用RETI代替RET会误中断标记。如中断服务程序中有调子程序动作,你用了RETI,结果可能会提前清除了中断标记,导致后面的程序有可能被新中断提前打断。所以两者就好不要混用。 |
简单地说:RETI有清除中断标志的功能,以便再次发生中断时(同级别或低级别的中断,当然也包括自身)能再次进入中断程序。而RET少了这个功能。其余功能相同。 RETI可以代替RET(当然没必要),反之则不行。 |
中断程序执行完成后,必须执行一条RETI,RETI会将堆栈中的1000H弹回PC,这样PC就又=1000H了。 这里提个问题让你研究一下,研究透了,你的水平就大有提高了。 如果:中断程序执行完成后,不执行【RETI】,而是执行一条【RET】问: 1、能不能回到 here:LJMP here 去(即返回1000H去执行) 2、会有什么后果。 考的是RET与RETI 的区别。 |
再说中断: 这时T0中断了,按规则T0中断会做下列事情: 1、将PC压堆栈,即将1000H压入堆栈(因为这时:PC=1000H) 2、强制PC=000BH 这样CPU就执行你的中断服务程序了,当然你的中断服务程序(T0中断)必须放在000BH开始的地方。 对于C语言,C的平台会自动帮你将T0中断服务程序放到这个地方的。 |
假设你的 here=1000H,在1000H:处放了这样三个字节:02 00 10 写成汇编也就是 here:LJMP here (注:将你的JMP改为LJMP,道理一样) 当CPU执行到1000H单元时,取到02,分析出这是LJMP指令,而这条指令的规则是PC=紧接后面两个字节,于是CPU续取两个字节放入PC,结果是:PC=1000H,这样就永远“死”在1000H处,其实不是死,记住:CPU永远不会死!!!!所谓“死”是CPU被“蒙圈”了。 |
CPU中有一个程序指针PC,以51为例,它是16位的,CPU从何处取指令分析执行,由PC说了算, 上电复位时PC=0,所以CPU从0000H开始执行程序。 T0中断时PC被强制写入000BH,所以中断发生后CPU会从000BH取指令运行。 |
楼主之所以提出这个问题,是对CPU是如何运行程序的不是太清楚,对中断如何执行与返回也不是太清楚。 下面我说给你听: |
从哪一语句发生的中断,中断服务程序执行完以后(RETI)会到产生中断处下一语句继续运行。 看堆栈栈顶很清楚。 |
程序执行到here:sjmp here和中断没有关系,执行到here:sjmp here后程序就不走了,原地踏步,这时如果有定时中断到来就进入中断服务程序,执行完后继续等待定时中断到来。 |
RETI是中断返回语句,意思是中断结束返回到断点继续运行,这个程序是在HERE处原地踏步,也可以认为是返回到HERE处运行, |