8.2.1 Organizing Modules

This section summarizes the organization of declarations and definitions in modules and include files and the use of the INCLUDE directive.

Include Files

Type declarations that need to be identical in every module should be placed in an include file. Doing so ensures consistency and can save programming time when updating programs. Include files should contain only symbol declarations and any other declarations that are resolved at assembly time. (See Section 1.3.1, “Generating and Running Executable Programs,” for a list of assembly-time operations.) If the include file is associated with more than one module, it cannot contain statements that define and allocate memory for symbols unless you include the data conditionally (see Section 1.3.3).

Modules

Label definitions that cause the assembler to allocate memory space must be defined in a module, not in an include file. If any of these definitions is located in the include file, it is copied into each file that uses the include file, creating an error.

Summary: Include files are inserted at the location of the INCLUDE directive.

Once you have placed public symbols in an include file, you need to associate that file with the main module. The INCLUDE statement is usually placed before data and code segments in your modules. When the assembler encounters an INCLUDE directive, it opens the specified file and assembles all its statements. The assembler then returns to the original file and continues the assembly process.

The INCLUDE directive takes the form

INCLUDE filename

where filename is the full name or fully specified path of the include file. For example, the following declaration inserts the contents of the include file SCREEN.INC in your program:

INCLUDE SCREEN.INC

Summary: You must make sure that the assembler can find include files.

The file name in the INCLUDE directive must be fully specified; no extensions are assumed. If a full path name is not given, the assembler searches first in the directory of the source file containing the INCLUDE directive.

If the include file is not in the source file directory, the assembler searches the paths specified in the assembler's command-line option /I, or in PWB's Include Paths field in the MASM Option dialog box (accessed from the Option menu). The /I option takes this form:

/I path

Multiple /I options can be used to specify that multiple directives be searched in the order they appear on the command line. If none of these directories contains the desired include file, the assembler finally searches in the paths specified in the INCLUDE environment variable. If the include file still cannot be found, an assembly error occurs. The related /x option tells the assembler to ignore the INCLUDE environment variable for all subsequent assemblies.

An include file may specify another include file. The assembler processes the second include file before returning to the first. Include files can be nested this way as deeply as desired; the only limit is the amount of free memory.

Summary: Put constants used in more than one module into the include file.

Include Files or Modules

You can use the EQU directive to create named constants that cannot be redefined in your program (see Section 1.2.4, “Integer Constants and Constant Expressions,” for information about the EQU directive). Placing a constant defined with EQU in an include file makes it available to all modules that use that include file.

Placing TYPEDEF, STRUCT, UNION, and RECORD definitions in an include file guarantees consistency in type definitions. If required, the variable instances derived from these definitions can be made public among the modules with EXTERNDEF declarations (see the next section). Macros (including macros defined with TEXTEQU) must be placed in include files to make them visible in other modules.

If you elect to use full segment definitions (along with, or instead of, simplified definitions), you can force a consistent segment order in all files by defining segments in an include file. This technique is explained in Section 2.3.2, “Controlling the Segment Order.”