ba_wang_mao 发表于 2008-12-30 08:58:25

请教马老师: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()时,所有的寄存器内容都发生变化,既然如此,又如何确保

  返回断点后,能够正确的执行呢?

avrmcu 发表于 2008-12-31 10:26:10

是栈不够,而非堆不够,对C/C++来讲只有使用malloc、new等分配变量时,使用的才是堆,ICC中可以进行相应的栈检查。

ba_wang_mao 发表于 2008-12-30 15:58:30

喔,谢谢。

  我总认为中断服务程序将现场压入到“硬件栈”中(最初学X8086汇编),原来ICC编译器将现场保存到“堆”中。

为什么ICC不将现场压入到“硬件栈”中,而压入到“堆”中,一般PC机上子程序中分配内存时,才用到“堆”。



  难怪,ICC编译中有个选项:Return Stack Size:16,当子程序嵌套调用层数多时,允许中断嵌套时,会出现奇怪的现象,

原来是“堆”空间不够。

  http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_565203.JPG

 (原文件名:未命名.JPG) 

machao 发表于 2008-12-30 14:59:07

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.

ba_wang_mao 发表于 2008-12-30 14:46:20

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指令呀!

machao 发表于 2008-12-30 13:41:10

如果不保存现场,这样的软件还能用吗?

你写个中断服务程序,服务程序中多做点计算的工作,再编译后看看有没有现场保护。

ba_wang_mao 发表于 2008-12-30 09:09:54

补充一点:

  如果PC机上中断服务程序如果采用汇编语言编写,如果使用了全部的寄存器,现场就必须保存全部寄存器,

如果仅仅使用了部分寄存器,保存现场时,可以只保存使用了的寄存器。

qzf368 发表于 2009-10-9 20:18:02

我的理解,在RAM够用的时候,栈可以设置大一些,防止溢出

qzf368 发表于 2009-10-10 00:52:34

不知道对不对啊 反正这个设置我也搞的比较晕

taocongrong 发表于 2011-12-18 12:22:50

页: [1]
查看完整版本: 请教马老师:ICC编译器,中断服务程序不保存现场,难以理解?【恢复】