I have been talking about program segments that are fixed, moveable, and discardable. These characteristics are called ”segment attributes.“ To tell Windows the attributes you want in your program segments, you use the CODE, DATA, and SEGMENTS statements in the module definition file. During linking, LINK encodes the attributes for each program segment into a 16-bit flag and stores this flag in the segment table of the .EXE file. Windows has access to these segment attributes when loading your code and data segments. The sample programs presented so far contain these two lines in their module definition files:
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
We have not yet encountered the SEGMENTS statement.
The CODE statement applies to all code segments within your program that are not explicitly listed in the SEGMENTS statement. Similarly, the DATA statement applies to all data segments except those listed in the SEGMENTS statement.
There are four standard attributes: ”load,“ ”memory,“ ”discardable,“ and ”instance.“
The ”load“ attribute can be either PRELOAD or LOADONCALL. This attribute tells Windows when to load the segment. The default is PRELOAD, which means that the code segment (or segments) should be loaded at the time the program begins execution. A LOADONCALL segment will be loaded into memory the first time it is needed. For a program with a single code module, it really doesn't matter which attribute you use. For programs with multiple code modules, you should use PRELOAD for segments that are required when the program first starts up (for instance, those that do initialization from WinMain) and LOADONCALL for the other code segments. To specify different attributes for multiple code segments, you must use the SEGMENTS statement, discussed later.
The ”memory“ attribute can be either FIXED or MOVEABLE. The default is FIXED. If you're writing normal Windows programs, you should have no problem specifying MOVEABLE. (Device drivers that must process hardware interrupts are another matter. These usually require one fixed code segment.)
The ”discardable“ attribute is indicated by the DISCARDABLE keyword. This indicates that Windows can discard the segment from memory and reload it from the .EXE file when necessary. Code segments in normal Windows programs should be flagged as DISCARDABLE. The default data segment cannot be flagged as DISCARDABLE.
The ”instance“ attribute is relevant only for data segments. It should be set to MULTIPLE for Windows programs, indicating that each instance gets its own data segments. The NONE and INSTANCE options are for Windows dynamic link libraries (discussed in Chapter 19), because Windows libraries can have only one instance. If the Windows library has a data segment, INSTANCE (or SINGLE) is used. If not, NONE is used.
The SEGMENTS statement lets you assign different segment attributes to other code and data segments within your program. The general form of the SEGMENTS statement is:
SEGMENTS segment-name [CLASS 'class-name'] [allocate] [attributes]
You'll probably use this statement most often if you create a medium-model program or a small-model program with multiple code segments. For a medium-model program, the C library functions and start-up code are in a code segment named _TEXT. Each source code module is assigned a different code segment name that by default is the filename of the source code file followed by _TEXT. For instance, if you have three source code modules called PROGRAM.C, MODULE1.C, and MODULE2.C, the PROGRAM.EXE file has four code segments: _TEXT, PROGRAM_TEXT, MODULE1_TEXT, and MODULE2_TEXT.
If you do not include a SEGMENTS statement, all four code modules take on the attributes from the CODE statements. If you do include a SEGMENTS statement, however, your results might look something like this:
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
SEGMENTS MODULE1_TEXT LOADONCALL MOVEABLE DISCARDABLE
MODULE2_TEXT LOADONCALL MOVEABLE DISCARDABLE
Now the _TEXT and PROGRAM_TEXT segments are PRELOAD and are loaded when the program first begins execution. MODULE1_TEXT and MODULE2_TEXT are LOADONCALL. Windows loads them only when they are needed.
If you use the SEGMENTS statement for data segments, you must include:
CLASS 'DATA'
By default, the class is CODE. You can also add a minimum allocation size to increase the size of the data segment when it's loaded into memory.