KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q90294: Using Large Memory Model, Microsoft C/C++, & Windows 3.1

Article: Q90294
Product(s): Microsoft Windows Software Development Kit
Version(s): WINDOWS:3.0,3.1
Operating System(s): 
Keyword(s): kb16bitonly
Last Modified: 30-AUG-2001

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Windows Software Development Kit (SDK) versions 3.0, 3.1 
-------------------------------------------------------------------------------

SUMMARY
=======


In Windows version 3.0, using the large memory model with Microsoft C version 6.0
is not recommended. For more information on the problems that occur when using
the large memory model under Windows 3.0, query this knowledge base on the
following words:

  large and model and protected

Windows version 3.1 and the Microsoft C/C++ version 7.0 compiler have resolved
most of these problems and make the large memory model much more suitable for
developing applications under Windows 3.1.

MORE INFORMATION
================

There are three main problems when using the large memory model under Windows:

1. Large model applications can have multiple data segments (this is always the
  case when compiling with Microsoft C 6.0). In Windows 3.0, these extra
  segments are loaded as FIXED and page-locked. Having a large amount of FIXED
  page-locked memory results in a serious degradation of the memory manager's
  performance. FIXED memory is allocated from the bottom of the global heap,
  which means it normally lies in conventional memory (below 1 MB), which is
  needed by the Windows loader when it loads a new module into memory. For more
  information on this topic, query this knowledge base on the following words:

  using and memory and below and megabyte

  This problem has been corrected in Windows 3.1. In Windows 3.1, an
  application's code and data segments are always loaded as MOVEABLE,
  regardless of the segment attributes specified in the application's
  definition (.DEF) file. A DLL's code and data segments are loaded exactly as
  they are specified in the DLL's .DEF file.

2. Under both Windows 3.0 and Windows 3.1, only one instance of an application
  with multiple data segments can be run at one time. This is because the
  Windows loader can't fix-up multiple instances of a far pointer because code
  is shared among all instances of an application.

  In most cases, this problem may be resolved by using the /Gx and /Gt compile
  options with the Microsoft C/C++ 7.0 compiler. The /Gx option causes the
  compiler to force static data into the default data segment, which results in
  the application having only one data segment. Note, however, that this works
  only if the application's static data, string literals, stack, and heap all
  fit into a 64K segment.

  The /Gt switch specifies the size a static object must be to be allocated its
  own data segment. When trying to create a single data segment, this threshold
  value should be large enough to ensure that no data objects are allocated
  outside of the default data segment. If the /Gt option is not specified, the
  data threshold will be 32767.

3. The final problem with using large model under both Windows 3.0 and Windows
  3.1 is the performance degradation that occurs when an application uses far
  pointers to access its data.

  When running under the protected mode of the Intel 286, 386, and 486
  processors, a far address is a combination of a selector and an offset. A
  selector is essentially an index into an array called a descriptor table. A
  descriptor is an 8-byte value that contains information about the segment,
  such as its base address, size, read/write privileges, and so forth.

  Whenever a far variable is referenced in protected mode, the processor must
  load the descriptor into one of the segment registers' descriptor cache and
  mark the descriptor as being accessed. This means that a reference to a far
  variable requires at least two reads from and one write to memory just to
  obtain the variable's linear address.

  Adding this delay to the time needed for performing far pointer arithmetic
  amounts to a significant loss of performance when compared to the medium
  model, which uses near pointers for data. One method to increase the
  performance of a large model application is to explicitly declare commonly
  used global or static variables as being NEAR, which causes the compiler to
  allocate the variable in the default data segment, and to use a near pointer
  when referencing the variable.

Conclusion
----------

Because Windows 3.1 and Microsoft C/C++ 7.0 have resolved most of the problems
related to use of the large memory model, developing application for Windows 3.1
with the large memory model is much more acceptable than it was under Windows
3.0 and Microsoft C 6.0.

Additional query words: 3.00 3.10

======================================================================
Keywords          : kb16bitonly 
Technology        : kbAudDeveloper kbWin3xSearch kbSDKSearch kbWinSDKSearch kbWinSDK300 kbWinSDK310
Version           : WINDOWS:3.0,3.1

=============================================================================

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.

Copyright Microsoft Corporation 1986-2002.