ID Number: Q79856
6.00 6.00a 6.00ax | 6.00 6.00a
MS-DOS | OS/2
Summary:
With Microsoft C versions 6.0, 6.0a, and 6.0ax, 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.
Please note that while the volatile keyword is accepted syntactically
by the C 5.1 compiler, the keyword had no effect.
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: 5.10 6.00 6.00a 6.00ax