PRB: Using Near Addresses in Interrupt Handlers in C

ID: Q42597

6.00 6.00a 6.00ax 7.00 | 1.00 1.50 1.51 1.52

MS-DOS                 | WINDOWS
kbprg kbprb

The information in this article applies to:

SYMPTOMS

When the Microsoft C Compiler compiles the sample program below for the small or medium memory model, it gives the following warning:

With compiler 5.1

   C4058 : address of frame variable taken, DS != SS

With compilers 6.0, 6.0a, 6.0ax

   C4058 : address of automatic (local) variable taken, DS != SS

With compilers 7.0, 8.0, and 8.0c (/f- option)

   C4762: near/far mismatch in argument; conversion supplied

CAUSE

The warning for the 6.0, 6.0a, and 6.0ax compilers is generated because the compiler assumes that DS is equal to SS. The compiler gives the warning when a near address that refers to a stack location is passed to an interrupt handler, because the stack segment SS could be changed.

The warning was changed in 7.0 and later because when SS != DS, the address of a local is considered to be a far pointer. Giving warning C4762 is more appropriate.

RESOLUTION

If the memory model is large or compact, or if the __far keyword is used when func's formal parameter is declared, the compiler will not give any warnings. When func is called, an address with the stack segment and the offset will be passed to the function automatically. Declaring the stack variable ch as static will also avoid the problem.

MORE INFORMATION

In general, in the small and medium memory models, data pointers are near unless explicitly declared with the __far keyword. In the example below, the function func is expecting a near address that is a 16-bit offset. A function such as func has no way to determine if the __near pointer passed to it is an offset relative to the data segment or the stack segment. Therefore, the C compiler makes the assumption that an offset by itself is always relative to the default data segment. This is not a problem in a normal case, where we can depend on the fact that SS will be equal to DS. However, in the example below, the stack segment could be changed in the interrupt handler; therefore, the compiler warns you that the code may not work as expected.

Sample Code:

/* Compile options needed: /AS or /AM and /f- (compiler 7.0 and later)
*/ 

void interrupt far handler( void );
void func( char * );

void interrupt __far handler( )
{
   char ch;              /* Change to static char ch for workaround */ 
   func( &ch );
}

void func( char *ptr )
{
   *ptr = 'a';
}

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

Last Reviewed: July 18, 1997