2.3.1 Defining Segments with the SEGMENT Directive

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.