The SEGMENT directive begins a segment, and the ENDS directive ends a segment:
name SEGMENT [[align]] [[READONLY]] [[combine]] [[use]] [['class']]
statements
name ENDS
The name defines the name of the segment. Within a module, all segment definitions with the same name are treated as though they reference the same segment. The linker also combines identically named segments from different modules unless the combine type is PRIVATE. In addition, segments can be nested.
Summary: Options used with the SEGMENT directive can be in any order.
The optional types that follow the SEGMENT directive give the linker and the assembler instructions on how to set up and combine segments. The list below summarizes these types; the following sections explain them in more detail.
Type | Description |
align | Defines the memory boundary on which a new segment begins. |
READONLY | Tells the assembler to report an error if it detects an instruction modifying any item in a READONLY segment. |
combine | Determines how the linker combines segments from different modules when building executable files. |
use (80386/486 only) | Determines the size of a segment. USE16 indicates that offsets in the segment are 16 bits wide. USE32 indicates 32-bit offsets. |
class | Provides a class name for the segment. The linker automatically groups segments of the same class in memory. |
Types can be specified in any order. You can specify only one attribute from each of these fields; for example, you cannot have two different align types.
Once you define a segment, you can reopen it later with another SEGMENT directive. When you reopen a segment, you need only give the segment name.
NOTE:
The PAGE align type and the PUBLIC combine type are distinct from the PAGE and PUBLIC directives. The assembler distinguishes them by means of context.
Aligning Segments
The optional align type in the SEGMENT directive defines the range of memory addresses from which a starting address for the segment can be selected. The align type can be any one of these:
Align Type | Starting Address |
BYTE | Next available byte address. |
WORD | Next available word address. |
DWORD | Next available doubleword address. |
PARA | Next available paragraph address (16 bytes per paragraph). Default. |
PAGE | Next available page address (256 bytes per page). |
The linker uses the alignment information to determine the relative starting address for each segment. The operating system calculates the actual starting address when the program is loaded.
Making Segments Read-Only
The optional READONLY attribute is helpful when creating read-only code segments for protected mode or when writing code to be placed in read-only memory (ROM). It protects against illegal self-modifying code.
The READONLY attribute causes the assembler to check for instructions that modify the segment and to generate an error if it finds any. The assembler generates an error if you attempt to write directly to a read-only segment.
Combining Segments
The optional combine type in the SEGMENT directive defines how the linker combines segments having the same name but appearing in different modules. The combine type controls linker behavior, not assembler behavior. The combine types are described in full detail in online help and are summarized below.
Combine Type | Linker Action |
PRIVATE | Does not combine the segment with segments from other modules, even if they have the same name. Default. |
PUBLIC | Concatenates all segments having the same name to form a single, contiguous segment. |
STACK | Concatenates all segments having the same name and causes the operating system to set SS:00 to the bottom and SS:SP to the top of the resulting segment. Data initialization is unreliable, as discussed below. |
COMMON | Overlaps segments. The length of the resulting area is the length of the largest of the combined segments. Data initialization is unreliable, as discussed below. |
MEMORY | Used as a synonym for the PUBLIC combine type. |
AT address | Assumes address as the segment location. An AT segment cannot contain any code or initialized data, but it is useful for defining structures or variables that correspond to specific far memory locations, such as a screen buffer or low memory. The AT combine type cannot be used in protected-mode programs. |
Do not place initialized data in STACK or COMMON segments. With these combine types, the linker overlays initialized data for each module at the beginning of the segment. The last module containing initialized data writes over any data from other modules.
NOTE:
Normally, you should provide at least one stack segment (having STACK combine type) in a program. If no stack segment is declared, LINK displays a warning message. You can ignore this message if you have a specific reason for not declaring a stack segment. For example, you would not have a separate stack segment in a DOS tiny model (.COM) program, nor would you need a separate stack in a DLL library that used the caller's stack.
Setting Segment Word Sizes (80386/486 Only)
The use type in the SEGMENT directive specifies the segment word size on the 80386/486 processors. Segment word size determines the default operand and address size of all items in a segment.
Summary: The 80386/486 can operate in 16-bit or 32-bit mode.
The size attribute can be USE16, USE32, or FLAT. If the 80386 or 80486 processor has been selected with the .386 or .486 directive, and this directive precedes .MODEL, then USE32 is the default. This attribute specifies that items in the segment are addressed with a 32-bit offset rather than a 16-bit offset. If .MODEL precedes the .386 or .486 directive, USE16 is the default. To make USE32 the default, put .386 or .486 before .MODEL. You can override the USE32 default with the USE16 attribute.
NOTE:
Mixing 16-bit and 32-bit segments in the same program is possible but usually is necessary only in systems programming.
Setting Segment Order with Class Type
Summary: Segments of the same class are grouped together in the executable file.
The optional class type in the SEGMENT directive helps control segment ordering. Two segments with the same name are not combined if their class is different. The linker arranges segments so that all segments identified with a given class type are next to each other in the executable file. However, within a particular class, the linker orders segments in the order encountered. The .ALPHA, .SEQ, or .DOSSEG directive determines this order in each .OBJ file. The most common application for specifying a class type is to place all code segments first in the executable file.