PRB: Using Near Addresses in Interrupt Handlers in C

Last reviewed: July 17, 1997
Article 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:

  • The C/C++ Compiler (CL.EXE) included with:

        - Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax
        - Microsoft C/C++ version 7.0
        - Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, and 1.52
    

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


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 17, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.