32-bit Memory Models

This chapter describes the various 32-bit memory models supported by Watcom C/C++. Each memory model is distinguished by two properties; the code model used to implement function calls and the data model used to reference data.

This chapter includes the following sections:

32-bit code models

There are two code models:

If your program contains less than 4GB of code, you should use a memory model that employs the small code model. This results in smaller and faster code, since near calls are smaller instructions and are processed faster by the CPU.

32-bit data models

There are two data models:

  • small data model - all references to data are made with near pointers. Near pointers are 32 bits; all data references are made relative to the segment value in segment register DS. Hence, in a small data model, all data comprising your program must be less than 4GB.
  • big data model - all references to data are made with far pointers. Far pointers are 48 bits (a 16-bit segment value and a 32-bit offset relative to the segment value).

    This removes the 4GB limitation on data size imposed by the small data model. However, when a far pointer is incremented, only the offset is adjusted. Watcom C/C++ assumes that the offset portion of a far pointer isn't incremented beyond 4GB. The compiler assigns an object to a new segment if the grouping of data in a segment causes the object to cross a segment boundary. Implicit in this is the requirement that no individual object exceed 4GB.

    QNX doesn't support the big data model.
If your program contains less than 4GB of data, you should use the small data model. This results in smaller and faster code, since references using near pointers produce fewer instructions.

Summary of 32-bit memory models

As previously mentioned, a memory model is a combination of a code model and a data model. The following table describes the memory models supported by Watcom C/C++.

Memory Model Code Model Data Model Default Code Pointer Default Data Pointer
flatsmallsmallnearnear
smallsmallsmallnearnear

Flat memory model

In the flat memory model, the application's code and data must total less than 4GB in size. Segment registers CS, DS, SS and ES point to the same linear address space (this doesn't imply that the segment registers contain the same value). That is, a given offset in one segment refers to the same memory location as that offset in another segment. Essentially, a flat model operates as if there were no segments.

Mixed 32-bit memory model

A mixed memory model application combines elements from the various code and data models. A mixed memory model application might be characterized as one that uses the near, far or huge keywords when describing some of its functions or data objects.

For example, a medium memory model application that uses some far pointers to data can be described as a mixed memory model. In an application such as this, most of the data is in a 4GB segment (DGROUP), and hence can be referenced with near pointers relative to the segment value in segment register DS. This results in the generation of more efficient code, and better execution times than one can expect from a big data model. Data objects outside of the DGROUP segment are described with the far keyword.

Linking applications for the various 32-bit memory models

Each memory model requires different runtime and floating-point libraries. Each library assumes a particular memory model, and should be linked only with modules that have been compiled with the same memory model. The following table lists the libraries that are to be used to link an application that has been compiled for a particular memory model. Currently, only libraries for the flat/small memory model are provided:

Runtime Library Floating-Point Library (80x87) Floating-Point Library (f-p calls)
clib3r.lib math387r.lib math3r.lib
clib3s.lib math387s.lib math3s.lib
plib3r.lib cplx73r.lib cplx3r.lib
plib3s.lib cplx73s.lib cplx3s.lib

The letter ``r'' or ``s'' that's affixed to the file name indicates the particular strategy with which the modules in the library have been compiled.

r
denotes a version of the Watcom C/C++ 32-bit libraries that have been compiled for the flat/small memory models using the 3r, 4r or 5r option.
s
denotes a version of the Watcom C/C++ 32-bit libraries that have been compiled for the flat/small memory models using the 3s, 4s or 5s option.

Memory layout

The following describes the segment ordering of an application linked by the Watcom Linker. Note that this assumes that the DOSSEG linker option has been specified.

  1. all USE16 segments. These segments are present in applications that execute in both real mode and protected mode. They are first in the segment ordering so that the REALBREAK option of the RUNTIME directive can be used to separate the real-mode part of the application from the protected-mode part of the application. Currently, the RUNTIME directive is valid for Phar Lap executables only.
  2. all segments not belonging to group DGROUP with class CODE
  3. all other segments not belonging to group DGROUP
  4. all segments belonging to group DGROUP with class BEGDATA
  5. all segments belonging to group DGROUP not with class BEGDATA, BSS or STACK
  6. all segments belonging to group DGROUP with class BSS
  7. all segments belonging to group DGROUP with class STACK

Segments belonging to class BSS contain uninitialized data. Note that this only includes uninitialized data in segments belonging to group DGROUP. Segments belonging to class STACK are used to define the size of the stack used for your application. Segments belonging to the classes BSS and STACK are last in the segment ordering, so that uninitialized data need not take space in the executable file.

In addition to these special segments, the following conventions are used by Watcom C/C++:

  1. The CODE class contains the executable code for your application. In a small code model, this consists of the segment _TEXT. In a big code model, this consists of the segment module_TEXT, where module is the file name of the source file.
  2. The FAR_DATA class consists of the following:
    • data objects whose size exceeds the data threshold in large data memory models (the data threshold is 32K unless changed using the zt compiler option)
    • data objects defined using the FAR or HUGE keyword
    • literals whose size exceeds the data threshold in large data memory models (the data threshold is 32K unless changed using the zt compiler option)
    • literals defined using the FAR or HUGE keyword.

You can override the default naming convention used by Watcom C/C++ to name segments:

  • The nm option for the Watcom C/C++ compiler can be used to change the name of the module. This, in turn, changes the name of the code segment when compiling for a big code model.
  • The nt option for the Watcom C/C++ compiler can be used to specify the name of the code segment, regardless of the code model used.