INF: Using the Linker /ALIGN Option

ID Number: Q47493

2.03 2.10 3.00

WINDOWS

Summary:

This article discusses various considerations regarding the Microsoft

Linker and its /ALIGN option when it is used to develop applications

for the Microsoft Windows environment. This information also applies

to the development of dynamic-link libraries (DLLs) for Windows.

More Information:

According to its definition, the Microsoft Linker /ALIGN option

"directs the linker to align segment data in the executable file along

the boundaries specified by 'size.'" The "size" parameter is in bytes

and must be a power of 2. Specifying /ALIGN:16 on the LINK line aligns

segments on 16-byte boundaries. Making an /ALIGN:16 specification is

recommended for Windows applications and dynamic-link libraries (DLLs)

because the default alignment is 512.

When the linker creates an EXE file and /ALIGN:16 is specified, if a

segment does not end on a 16-byte boundary, the segment is padded with

extra bytes. The next segment always begins at a 16-byte boundary.

If an application contains several small segments, and no /ALIGN

option is specified on the Linker command line, each segment will

contain a great deal of wasted space and the resulting EXE file will

be unnecessarily large. The amount of wasted space is computed as

follows:

waste = align - (segment modulo align)

Therefore, for a 514-byte segment, an align size of 512 causes 510

bytes to be wasted. However, for the same segment, an alignment size

of 2 bytes does not waste any space.

Problems can arise when the Linker creates a very large EXE file using

a small align value because the size of the EXE may exceed the range

of values that can be represented by the EXE header segment table.

To demonstrate the problems that can arise, consider a very large EXE

file that is linked with an align size of 2. During the process of

creating this EXE file, the Linker puts segment 42 at file offset

380,000 and records the position in the New EXE Segment Table. The

format of this table is as follows:

Offset Length Contents

------ ------ --------

0h 2 Offset of segment relative to beginning of file

after shifting value left by alignment shift count.

2h 2 Length of segment (0h for segment of 65536 bytes).

4h 2 Segment flag word.

6h 2 Minimum allocation size for segment; that is,

amount of space Windows reserves in memory for the

segment (0h for minimum allocation size of 65536

bytes).

In this case, the offset of the segment to place in the table is

(380,000 >> 1) = 190,000, which is too large to store in a 16-bit word

(the maximum value is 65,535). Therefore, 58,928 (the low-order 16

bits of 190,000) is stored. Unfortunately, the Linker does not provide

any warning of the data loss involved with this step.

When Windows loads segment 42 from the EXE file, it takes the value

58,928 and multiplies it by the align size (2), which results in an

offset of 117,856 and does not lead to the desired segment in the

file.

For more information on the new EXE (New Executable) file header

format, see appendix K (pages 1488-1497) of the "MS-DOS Encyclopedia"

(Microsoft Press).

Additional reference words: 2.03 2.10 3.00 2.x s_link