Microsoft KB Archive/80384

= PRB: Span-Dependent Value Behavior Changes in N-Pass Assembly =

Article ID: 80384

Article Last Modified on 10/17/2003

-

APPLIES TO


 * Microsoft Macro Assembler 6.0 Standard Edition
 * Microsoft Macro Assembler 6.0a
 * Microsoft Macro Assembler 6.0b
 * Microsoft Macro Assembler 6.1 Standard Edition
 * Microsoft Macro Assembler 6.1a
 * Microsoft Macro Assembler 6.11 Standard Edition

-



This article was previously published under Q80384



SYMPTOMS
When the Microsoft Macro Assembler (MASM) assembles code that depends on the difference between the values of two labels (a span-dependent value), the results of an assembly by MASM versions 6.0 or later differs from the results produces by an earlier version of MASM.

Specifically, the difference occurs when the application uses a span- dependent value in one of the following cases:


 * In the expression for a preprocessor directive, like IF
 * In the expression for a predefined macro, like REPEAT or WHILE
 * In the arguments to a MACRO or TEXTEQU statement preceded by % (percent sign)



CAUSE
MASM versions 5.1 and earlier are two-pass assemblers; MASM versions 6.0 and later are N-pass assemblers.



RESOLUTION
Avoid using a span-dependent value in a preprocessor directive or in a predefined macro. If the code requires a span-dependent value, create and review a listing file to determine that each span-dependent value is evaluated as desired.

Avoid using the % operator with span-dependent values. The assembler evaluates an expression containing the % operator on the first pass. In many cases, the assembler produces the desired results when you remove the % operator and delay expression evaluation to a later pass.



STATUS
This behavior is under review and may or may not change in a future release.



MORE INFORMATION
MASM versions 5.1 and earlier are two-pass assemblers. The source file is read twice to determine the size of the instructions and the location of labels.

MASM versions 6.0 and later are N-pass assemblers. 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 its first pass through the application code. These values include expressions in preprocessor directives, expressions in predefined macros, and arguments preceded by the % operator. If one of these values is based on the difference between the values of two labels, the results may differ from those generated by MASM versions 5.1 and earlier.

The difference occurs because the assembler evaluates expressions and arguments based on the undetermined label locations available during the first assembly pass that may change in a subsequent assembly pass. Typically, the value changes when a forward reference occurs between the two labels. Because the assembler adds padding bytes for the forward reference and removes the padding in subsequent assembly passes, the second label has a larger value during the first assembly pass than in subsequent passes.

The code example below demonstrates this behavior. Specify the /Fl assembler option switch to create a listing file. Review the listing file to see how the assembler processes a span-dependent value.

The following information is part of the README.TXT file distributed with MASM version 6.1:   Span-Dependent Expressions used in Macros -

MASM 6.1 evaluates macro expressions only on the first pass of assembly, but code and data are reevaluated on subsequent passes. Because of this, macro expressions which depend on the span between two addresses may not evaluate correctly. For example, the following code will not evaluate correctly:

Label1: JMP Label2 Label2: REPEAT Label2 - Label1 ; Evaluates incorrectly INC AX     ENDM

View the listing file to determine if a questionable macro expression was evaluated as desired.

Span-Dependent Text Equates ---

The TEXTEQU operator is evaluated on the first assembly pass. If TEXTEQU is used with an expression that depends on the difference between two addresses, the resulting constant may be incorrect. For example, the following code will not evaluate correctly:

Label1: JMP Label2 Label2: WrongNum TEXTEQU %Label2-Label1 ; WrongNum will be incorrect

Sample Code ---


 * Assemble options needed in MASM 6.x: /c /Fl

_text  SEGMENT para public 'CODE' ASSUME cs:_text start: jmp SHORT forward forward: mov ax, 4C00h int 21h _text  ENDS

count = offset forward - offset start

IF count LT 6 %OUT two-pass assembler  ; MASM 5.1 and earlier shows this message ELSE %OUT n-pass assembler    ; MASM 6.0 and later shows this message ENDIF

tst1   SEGMENT para public index = 0 WHILE index LT count DB 1         ; This will be repeated 10 times in MASM 6.x. index = index + 1 ENDM tst1   ENDS

tst2   SEGMENT para public REPT count     ; This will be repeated 10 times in MASM 6.x,          DB 1          ; twice in MASM 5.1. ENDM tst2   ENDS

mac3   MACRO arg1 macvar = arg1 ENDM

tst3   SEGMENT para public mac3 %count    ; This will set macvar to 10 in MASM 6.x tst3    ENDS            ; and to 2 in MASM 5.1.

txt4   TEXTEQU %count

tst4   SEGMENT para public txtvar DB txt4         ; This will set txtvar to 10 in MASM 6.x. tst4    ENDS

END start

Additional query words: 6.00 6.00a 6.00b 6.10

Keywords: KB80384

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.