INF: DUP, REPT, MACRO Behavior May Change in N-Pass Assembly

ID Number: Q80384

6.00 | 6.00

MS-DOS | OS/2

Summary:

In the Microsoft Macro Assembler (MASM) version 6.0, if the size for a

DUP directive, the count for a REPT directive, or arguments to a MACRO

preceded by % (percent sign) depend on the difference between two

labels, the result of the assembly may differ from previous versions

of MASM.

More Information:

MASM 5.1 and earlier were two-pass assemblers. In a two-pass

assembler, the source file is read twice to determine the size of

instructions and the location of labels.

MASM 6.0 is an n-pass assembler. In an n-pass assembler, the assembler

scans the source until it can determine the size of all instructions

and the location of all labels; however, an n-pass assembler must

determine certain values on the first pass of the source. These values

include the size for DUP directives, the count for REPT directives,

and MACRO arguments preceded by %. If these values are based on the

difference between two labels, the results may differ from MASM 5.1

and earlier.

This occurs because the size of DUP, the count for REPT, or the value

of a MACRO argument preceded by % will be based on undetermined label

locations during the first assembly pass. These label values are only

approximations during the first pass of the assembly process and may

change during subsequent passes. This is typically a problem when a

forward reference occurs between the two labels. The assembler may add

padding bytes for the forward reference and then eliminate these bytes

during subsequent assembly passes. This may cause the second label to

have a larger value during the first assembly pass than the actual

value after all padding bytes have been removed.

Because the difference between two labels may change in n-pass assembly,

the use of label differences should be avoided in DUP, REPT, and as

MACRO arguments preceded by %.

The sample code below demonstrates this behavior.

Sample Code

-----------

; Assemble options needed: none

tst1 SEGMENT para public

ASSUME cs:tst1

start:

jmp SHORT forward

forward:

mov ax, 4C00h

int 21h

tst1 ENDS

count = offset forward - offset start

tst2 SEGMENT para public

REPT count ; This will be repeated 10 times in

DB 1 ; MASM 6.0 and 2 times in MASM 5.1.

ENDM

tst2 ENDS

tst3 SEGMENT para public

DB count DUP (2) ; This will be a DUP of 10 in.

tst3 ENDS ; MASM 6.0 and 2 in MASM 5.1.

mac4 MACRO arg1

macvar = arg1

ENDM

tst4 SEGMENT para public

mac4 %count ; This will set macvar to 10 in

tst4 ENDS ; MASM 6.0 and 2 in MASM 5.1.

END start

Additional reference words: 5.10 6.00