2.3.2 Controlling the Segment Order

The assembler normally positions segments in the object file in the order in which they appear in source code. The linker, in turn, processes object files in the order in which they appear on the command line. Within each object file, the linker outputs segments in the order they appear, subject to any group, class, and .DOSSEG requirements.

You can usually ignore segment ordering. However, it is important whenever you want certain segments to appear at the beginning or end of a program or when you make assumptions about which segments are next to each other in memory. For tiny model (.COM) programs, code segments must appear first in the executable file, because execution must start at the address 100h.

Segment Order Directives

You can control the order in which segments appear in the executable program with three directives. The default, .SEQ, arranges segments in the order in which they are declared.

The .ALPHA directive specifies alphabetical segment ordering within a module. .ALPHA is provided for compatibility with early versions of the IBM assembler. If you have trouble running code from older books on assembly language, try using .ALPHA.

The .DOSSEG directive specifies the DOS segment-ordering convention. It places segments in the standard order required by Microsoft languages. Do not use .DOSSEG in a module to be called from another module.

The .DOSSEG directive orders segments in this order:

1.Code segments

2.Data segments, in this order:

A.Segments not in class BSS or STACK

B.Class BSS segments

C.Class STACK segments

When you declare two or more segments to be in the same class, the linker automatically makes them contiguous. This rule overrides the segment-ordering directives. (See “Setting Segment Order with Class Type” in the previous section for more about segment classes.)

Linker Control

Most of the segment-ordering techniques (class names, .ALPHA, .SEQ) control the order in which the assembler outputs segments. Usually, you are more interested in the order in which segments appear in the executable file. The linker controls this order.

The linker processes object files in the order in which they appear on the command line. Within each module, it then outputs segments in the order given in the object file. If the first module defines segments DSEG and STACK and the second module defines CSEG, then CSEG is output last. If you want to place CSEG first, there are two ways to do so.

Summary: .DOSSEG handles segment ordering.

The simpler method is to use .DOSSEG. This directive is output as a special record to the object file linker, and it tells the linker to use the Microsoft segment-ordering convention. This convention overrides command-line order of object files, and it places all segments of class 'CODE' first. (See Section 2.3.1, “Defining Segments with the SEGMENT Directive.”)

The other method is to define all the segments as early as possible (in an include file, for example, or in the first module). These definitions can be “dummy segments”—that is, segments with no content. The linker observes the segment ordering given, then later combines the empty segments with segments in other modules that have the same name.

For example, you might include the following at the start of the first module of your program or in an include file:

_TEXT SEGMENT WORD PUBLIC 'CODE'

_TEXT ENDS

_DATA SEGMENT WORD PUBLIC 'DATA'

_DATA ENDS

CONST SEGMENT WORD PUBLIC 'CONST'

CONST ENDS

STACK SEGMENT PARA STACK 'STACK'

STACK ENDS

Later in the program, the order in which you write _TEXT, _DATA, or other segments does not matter because the ultimate order is controlled by the segment order defined in the include file.