请教马老师:ICC编译器,中断服务程序不保存现场,难以理解?【恢复】
1、普通PC机上的编译器(如BORLAND C),进入中断服务程序之前,(1)、首先保存断点位置(PC指针)
(2)、跳转到中断服务程序
(3)、然后保存断点处现场(AX,BX,CX,DX,SI,DI,ES,DS,等等)
2、ICC编译器不保存现场,从中断退出后,如何恢复现场
3、如果允许中断嵌套(即每个中断服务程序第一条指令为SEI()),假如:正在执行函数F_A()时,被T0中断打断,
而T0中断正在执行时,又被T1中断打断,T1中断正在被执行时,又被T2中断打断。
最后执行完所有的中断服务程序后,返回到函数F_A()时,所有的寄存器内容都发生变化,既然如此,又如何确保
返回断点后,能够正确的执行呢? 是栈不够,而非堆不够,对C/C++来讲只有使用malloc、new等分配变量时,使用的才是堆,ICC中可以进行相应的栈检查。 喔,谢谢。
我总认为中断服务程序将现场压入到“硬件栈”中(最初学X8086汇编),原来ICC编译器将现场保存到“堆”中。
为什么ICC不将现场压入到“硬件栈”中,而压入到“堆”中,一般PC机上子程序中分配内存时,才用到“堆”。
难怪,ICC编译中有个选项:Return Stack Size:16,当子程序嵌套调用层数多时,允许中断嵌套时,会出现奇怪的现象,
原来是“堆”空间不够。
http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_565203.JPG
(原文件名:未命名.JPG) 1F7E 2990 ld R2,y+
1F80 2FBE out 0x3f,R2
1F82 3990 ld R3,y+
1F84 2990 ld R2,y+
1F86 1895 reti
这里是做什么的?
每个软件采用中断现场保护的方法不同,不一定就是使用PUSH和POP,压到硬件堆栈中的。通常可能建立软件堆栈,并使用它进行保护的。
本贴被 machao 编辑过,最后修改时间:2008-12-30,15:14:54. SHORT volatile USART1_receCount = 0;
UCHAR volatile USART1_checkoutError = 0;
#pragma interrupt_handler USART1_TX_ISR:iv_USART1_TX
void USART1_TX_ISR(void)
{
USART1_checkoutError = 0;
USART1_receCount = 0;
RS485_RECIVE();
}
1F6C ; #pragma interrupt_handler USART1_TX_ISR:iv_USART1_TX
1F6C ; void USART1_TX_ISR(void)
1F6C ; {
1F6C .dbline 1304
1F6C ; USART1_checkoutError = 0;
1F6C 2224 clr R2
1F6E 20920400 sts _USART1_checkoutError,R2 // 0 --->USART1_checkoutError
1F72 .dbline 1305
1F72 ; USART1_receCount = 0;
1F72 3324 clr R3
1F74 30920200 sts _USART1_receCount+1,R3 // 0 --->USART1_receCount 高字节
1F78 20920100 sts _USART1_receCount,R2 // 0 --->USART1_receCount 低字节
1F7C .dbline 1306
1F7C ; RS485_RECIVE();
1F7C C79A sbi 0x18,7 //
1F7E .dbline 1306
1F7E .dbline -2
1F7E L627:
1F7E .dbline 0 ; func end
1F7E 2990 ld R2,y+
1F80 2FBE out 0x3f,R2
1F82 3990 ld R3,y+
1F84 2990 ld R2,y+
1F86 1895 reti
1F88 .dbend
.area bss(ram, con, rel)
0000 .dbfile D:\USART1.C
0000 _USART1_mscomm_buffer::
0000 .blkb 255
00FF .dbsym e USART1_mscomm_buffer _USART1_mscomm_buffer Ac
00FF _USART1_send_buffer::
00FF .blkb 255
01FE .dbsym e USART1_send_buffer _USART1_send_buffer Ac
01FE ; }
上面的代码中,没有看到push指令呀! 如果不保存现场,这样的软件还能用吗?
你写个中断服务程序,服务程序中多做点计算的工作,再编译后看看有没有现场保护。 补充一点:
如果PC机上中断服务程序如果采用汇编语言编写,如果使用了全部的寄存器,现场就必须保存全部寄存器,
如果仅仅使用了部分寄存器,保存现场时,可以只保存使用了的寄存器。 我的理解,在RAM够用的时候,栈可以设置大一些,防止溢出 不知道对不对啊 反正这个设置我也搞的比较晕
页:
[1]