Preventing Code Removal During Optimization in an ISR

ID: Q79856

6.00 6.00a 6.00ax 7.00 | 6.00 6.00a | 1.00 1.50

MS-DOS                 | OS/2       | WINDOWS
kbprg

The information in this article applies to:

SUMMARY

With Microsoft C version 6.0 and later, the optimizer may not generate code for statements in an interrupt service routine (ISR) that modifies variables that the optimizer cannot tell are used later on.

Use of the keyword "volatile" can prevent this unwanted optimization from occurring.

MORE INFORMATION

The parameters for function ISR below are not passed on the stack as the C code seems to indicate. They are set up with code that the keyword _interrupt causes to be generated: a pusha on startup and a popa on exit if 286 code is generated; the equivalent pushes and pops otherwise. The parameters are placed in the function declaration to provide a convenient way to access the register values that have been placed on the stack.

However, as far as the C function is concerned, these parameters are passed by value and their values will not be used outside of this function. Therefore, the optimizer won't generate any code for the example below because it does not know that the register values will be restored.

The volatile keyword tells the compiler that the variable may be used outside of a function in ways that it cannot know about. Therefore, the optimizer will leave the code that involves the variable alone. To generate code for the variable modifications in the example, specify the two parameters used in the function as volatile unsigned _di and volatile unsigned flags in the parameter list.

For a similar example involving a variable that is not part of the parameter list, query on the following words:

   ISRs and side effects and signal handlers and optimizer

Compiling the sample code below with the options shown in the comment will produce a .COD file. This file will show what assembly code is generated for certain lines in the file.

Sample Code

/* Compile options needed: /c /Ox /G2 /Fc
*/ 

/* Remove comments on the keyword volatile to prevent unwanted
   code removal. */ 

void _interrupt _far ISR( unsigned _es, unsigned _ds,
                          /* volatile */ unsigned _di,
                          unsigned _si, unsigned _bp, unsigned _sp,
                          unsigned _bx, unsigned _dx, unsigned _cx,
                          unsigned _ax, unsigned _ip, unsigned _cs,
                          unsigned /* volatile */ flags )
{
   _di = 1;

   flags = flags & 0xfffe;
}

Additional reference words: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00 8.00 8.00c KBCategory: kbprg KBSubcategory: CLIss Keywords : kb16bitonly

Last Reviewed: July 18, 1997