Using OFFSET & SEG on Local Variables in Inline Assembly

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 Keywords : kb16bitonly

Last Reviewed: July 18, 1997