PRB: Using Near Addresses in Interrupt Handlers in C

ID Number: Q42597

5.10 6.00 6.00a 6.00ax

MS-DOS

Summary:

SYMPTOMS

When the Microsoft C Compiler compiles the sample program below for

the small or medium memory model, it gives the following warning:

Under C 5.1

-----------

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

Under C 6.0, 6.0a, 6.0ax

------------------------

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

CAUSE

The warning for the C 5.1, 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.

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.

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.

Sample Code:

------------

/* Compile options needed: /AS or /AM

*/

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: 5.00 5.10 6.00 6.00a 6.00ax