INF: Preventing Code Removal During Optimization in an ISR

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