取堆栈中的PC值一般采用2种方法:1.利用PUSH/POP;.........................XXXXH: lcall _getPC;YYYYH: ;................等效为:PUSH low YYYYH ;先压入低8位地址,SP+1PUSH high YYYYH ;后压入高8位地址,SP+1JMP _getPC;跳入_getPC后遇到RET返回YYYYH_getPC: pop DPTH ;先弹出高8位地址,SP-1 pop DPTL ;后弹出低8位地址,SP-1;...................................; 假设此处立即响应某中断;...................................ZZZZH: INC SP ;恢复低8位地址low YYYYH INC SP ;恢复高8位地址high YYYYH;...................................;................................... RET ;返回YYYYH 但若在第1个INC SP前来中断时,则由于2个POP和中断的2个PUSH将使原栈顶存入的返回地址YYYYH被中断返回地址ZZZZH覆盖!!! 以上程序等效为:;.........................XXXXH: lcall _getPC;YYYYH: ;................等效为:PUSH low YYYYH ;先压入低8位地址,SP+1PUSH high YYYYH ;后压入高8位地址,SP+1JMP _getPC;跳入_getPC后遇到RET返回YYYYH_getPC: POP DPTH ;先弹出高8位地址YYYYH,SP-1 POP DPTL ;后弹出低8位地址YYYYH,SP-1;...................................; 假设此处立即响应某中断(INT0) PUSH low ZZZZH;覆盖YYYYH!!!,SP+1 PUSH high ZZZZH;覆盖YYYYH!!!,SP+1 JMP 0x0003;跳入INT0_ISR;遇RETI返回ZZZZH,且SP-2;...................................ZZZZH: INC SP ;恢复低8位地址low ZZZZH INC SP ;恢复高8位地址high ZZZZH;...................................;................................... RET ;返回ZZZZH;哈哈,等效为SP-2,JMP ZZZZH结果很震惊---死循环!!!!!!!!!!!!!!!!!!!!!!!!!!!所以,这种方法要特别注意!!!---也是一种中断如何"伤人"的案例.2.利用SP,@R0;.........................XXXXH: lcall _getPC;YYYYH: ;................_getPC: MOV R0,SP;取SP是安全的 MOV DPTH, @R0;先弹出高8位地址YYYYH DEC R0 MOV DPTL, @R0;再弹出低8位地址YYYYH.............................................. RET这种方法不受中断的影响,因为用户没有操作SP(没改变其值)...

评论