Using OFFSET & SEG on Local Variables in Inline Assembly

Last reviewed: July 17, 1997
Article ID: Q69012
6.00 6.00a 6.00ax 7.00 | 1.00 1.50
MS-DOS                 | WINDOWS
kbtool

The information in this article applies to:

  The Microsoft 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 and 1.5

SUMMARY

Inline assembly allows you to use the SEG and OFFSET operators to get the segment and offset address of variables. However, if you use the SEG directive on a local variable, you will get the following error message when using products listed in the banner above:

   error C2415: improper operand type

In C versions 6.0, 6.0a, and 6.0ax, and C/C++ versions 7.0 and 7.0a, using the OFFSET directive on a local variable will not directly give you a near pointer to the variable. Because of this, it was decided to produce the C2415 error for this condition in C/C++ versions 8.0 and 8.0c.

MORE INFORMATION

It is important to remember that a local variable is placed on the stack at run time. Therefore, the compiler cannot determine its address at compile time. The value returned by OFFSET applied to a local variable actually is that variable's position on the stack relative to the BP register. Thus, adding the BP register to the OFFSET value will create a near pointer into the stack segment.

Because the local variable is on the stack, the segment value of a local variable is simply the stack segment (SS) register. The following two sample programs demonstrate the incorrect and correct method to access a local variable address:

Sample Code

// These programs show how you might try to load an address
// of a local variable into the dx, ax register combination.
// This is the wrong way to get a local variable address.

void main(void)
{
   int myvar;
   _asm
   {
      mov ax, OFFSET myvar
      mov dx, SEG myvar
   }
}

// This is the right way to get a local variable address.

void main (void)
{
   int myvar;
   _asm
   {
      lea ax, myvar
      add ax, bp
      mov dx, ss
   }
}


Additional reference words: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00 8.00
8.00c
KBCategory: kbtool
KBSubcategory: CLIss
.END:
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.