In some cases, MASM 6.0 with OPTION M510 does not support MASM 5.1 behavior. Several of these changes result from correcting bugs reported against MASM 5.1. To update your code to MASM 6.0, use the instructions in this section. This usually requires only minor changes.
Many of the items listed in this section will not exist in your code. The items most likely to occur are listed first, followed by those that are less likely to occur.
In addition, you may have conflicts between identifier names and new reserved words. You can use OPTION NOKEYWORD to resolve errors generated due to use of reserved words as identifiers. See Section A.2.2.9 for more information.
This section lists the differences between MASM 5.1 and MASM 6.0 due to bug corrections from MASM 5.1.
Invalid Use of LOCK, REPNE, and REPNZ
MASM 6.0 flags illegal uses of the instruction prefixes LOCK, REPNE, and REPNZ. The error generated for invalid uses of the LOCK, REPNE, and REPNZ prefixes is error A2068:
instruction prefix not allowed
Table 0.1 summarizes the correct use of the instruction prefixes. It lists each string instruction with the type of repeat prefix it uses and indicates whether the instruction works on a source, a destination, or both.
Table 0.1 Requirements for String Instructions
Instruction | Repeat Prefix | Source/Destination | Register Pair |
MOVS | REP | Both | DS:SI, ES:DI |
SCAS | REPE/REPNE | Destination | ES:DI |
CMPS | REPE/REPNE | Both | DS:SI, ES:DI |
LODS | None | Source | DS:SI |
STOS | REP | Destination | ES:DI |
INS | REP | Destination | ES:DI |
OUTS | REP | Source | DS:SI |
No Closing Quotation Marks in Macro Arguments
In MASM 5.1, both single and double quotation marks (' and ") can be used to begin strings in macro arguments, and the assembler does not generate an error or warning if the string does not end with quotation marks on a macro call. Instead, the assembler considers the remainder of the line to be part of the macro argument containing the opening quote (as if there were a closing quotation mark at the end of the line).
By default, MASM 6.0 now generates error A2046:
missing single or double quotation mark in string
so all single and double quotation marks in macro arguments must be matched. (Angle brackets not enclosed by brackets must also be matched.)
To correct errors the assembler finds, either end the string with a closing quotation mark as shown in this example, or use the macro escape character (!) to treat the quotation mark literally.
; MASM 5.1 code
MyMacro "all this in one argument
; Default MASM 6.0 code
MyMacro "all this in one argument"
MASM 5.1 considers code labels defined with a single colon inside a procedure to be local to that procedure if the module contains a .MODEL directive with a language type. Although the label is local, MASM 5.1 does not generate an error if it is also declared PUBLIC. MASM 6.0 generates error A2203:
cannot declare scoped code label as PUBLIC.”
If you want to make the label PUBLIC, it must not be local. You can use the double colon operator to define a non-scoped label, as shown in this example:
PUBLIC publicLabel
publicLabel:: ; Non-scoped label MASM 6.0
Byte Form of BT, BTS, BTC, and BTR Instructions
MASM 5.1 allows a byte argument for the 80386 bit-test instructions, but encodes it as a word argument. The byte form is not supported by the processor.
MASM 6.0 does not support this behavior and generates error A2024:
invalid operand size for instruction
Rewrite your code to use a word-sized argument.
Default Values for Record Fields
In MASM 5.1, default values for record fields can range down to –2n (where n is the number of bits in the field), resulting in the loss of the sign bit.
The allowed range for default values in MASM 6.0 is –2n–1 to 2n–1. Illegal initializers generate error A2071:
initializer too large for specified size
MASM 6.0 makes some changes in MASM 5.1 behavior to make the language more consistent. These design changes are not affected by the OPTION directive. Therefore, they require revisions in your code. In most cases, the necessary revisions are minor and the circumstances requiring changes are rare.
Conflicting Structure Definitions
MASM 5.1 allows two structures to be defined with the same name. The second definition replaces the first definition. However, the fields from the first are still defined. MASM 6.0 does not allow conflicting definitions of a structure. Errors A2160 through A2165 are generated when the assembler finds a conflicting definition. Each error notes a specific conflict, such as conflicting number of fields, conflicting names of fields, or conflicting initializers.
Forward References to Text Macros Outside of Expressions
MASM 5.1 allows forward references to text macros in specialized cases. MASM 6.0 with OPTION M510 also permits forward references, but only when the text macro is referenced in an expression. To revise your code, place all macro definitions at the beginning of the file.
HIGH and LOW Applied to Relocatable Operands
In MASM 5.1, applying HIGH and LOW to relocatable memory expressions is acceptable in some cases. For example, MASM 5.1 allows this code sequence:
; MASM 5.1 code
EXTRN var1:WORD
var2 DW 0
mov al, LOW var1 ; These two instructions yield the
mov ah, HIGH var1 ; same as mov ax, OFFSET var1
However, mov ax, LOW var2 is not legal. MASM 6.0 generates error A2105:
HIGH and LOW require immediate operands
The OFFSET operator is required on these operands in MASM 6.0, as shown below. Rewrite your code if necessary.
; MASM 6.0 code
mov al, LOW OFFSET var1
mov ah, HIGH OFFSET var2
OFFSET Applied to Group Names and Indirect Memory Operands
In MASM 6.0, you cannot apply OFFSET to a group name, indirect argument, or procedure argument. Doing so generates error A2098:
invalid operand for OFFSET
LENGTH Operator Applied to Record Types
In MASM 5.1, the LENGTH operator, when applied to a record type, returns the total number of bits in a record definition.
In MASM 6.0, the statement LENGTH recordName returns error A2143:
expected data label
Rewrite your code if necessary. The new SIZEOF operator returns information about records in MASM 6.0. See Section 5.3.2, “Defining Record Variables,” for more information.
Signed Comparison of Hexadecimal Values Using GT, GE, LE, or LT
The rules for two's-complement comparisons have changed. In MASM 5.1, the statement
0FFFFh GT -1
is false because the two's-complement values are equal. However, because hexadecimal numbers are now treated as unsigned, the expression is true in MASM 6.0. To update, rewrite the affected code.
RET Used with a Constant in Procedures with Epilogues
By default in MASM 6.0, the RET instruction followed by a constant suppresses automatic generation of epilogue (stack cleanup) code. MASM 5.1 ignores the operand and generates the epilogue. Remove the argument if necessary. See Section 7.3.8, “Generating Prologue and Epilogue Code.”
Code Labels at Top of Procedures with Prologues
By default in MASM 5.1, a code label defined on the same line as the first procedure instruction refers to the first byte of the prologue (the stack frame setup).
In MASM 6.0, a code label defined at the beginning of a procedure refers to the first byte of the procedure after the prologue. If a label is needed before the prologue, then the label must be placed before the PROC statement. See Section 7.3.8, “Generating Prologue and Epilogue Code,” for more information.
Use of % as an Identifier Character
MASM 5.1 allows % as an identifier character. This undocumented behavior leads to ambiguities when % is used as the expansion operator in macros. Since % is not allowed as a character in MASM 6.0 identifiers, you must change the names of any identifiers containing the % character. See Section 1.2.2 for a list of legal identifier characters.
MASM 6.0 does not require the use of the ASSUME statement for the CS register. Instead, MASM 6.0 generates an automatic ASSUME statement for the code segment register to the current segment or group (see Section 2.3.3). Additionally, MASM 6.0 does not allow explicit ASSUME statements for CS that contradict the automatically set ASSUME statement.
MASM 5.1 allows CS to be assumed to the current segment, even if that segment is a member of a group. With MASM 6.0, this results in warning A4004:
cannot ASSUME CS
To avoid this warning with MASM 6.0, delete the ASSUME statement for CS.
MASM 6.0 does not perform the standard two source passes that previous versions do. Therefore pass-dependent constructs are no longer meaningful.
Because MASM 6.0 assembles in one pass, the directives referring to two passes are no longer supported. These include .ERR1, .ERR2, IF1, IF2, ELSEIF1, and ELSEIF2. If you use IF2 or .ERR2, the assembler generates error A2061:
[ELSE]IF2/.ERR2 not allowed : single-pass assembler
The .ERR1 directive is treated as though it were .ERR, and the IF1 directive is treated as though it were IF.
MASM 5.1 directives that refer to the first pass are always true. Directives that refer to the second pass are flagged as errors. This change requires you to rewrite the affected code, since OPTION M510 does not enable this behavior.
You typically use pass-sensitive directive when doing the following: (Each example shows a MASM 6.0 rewrite.)
Declaring var external only if it is not defined in this module:
; PREVIOUS VERSIONS OF MASM:
IF2
IFNDEF var
EXTRN var:far
ENDIF
ENDIF
; MASM 6.0:
EXTERNDEF var:far
Including a file of definitions only once to speed assembly:
; PREVIOUS VERSIONS OF MASM:
IF1
INCLUDE file1.inc
ENDIF
; MASM 6.0:
INCLUDE FILE1.INC
Generating a %OUT or .ERR message only once:
; PREVIOUS VERSIONS OF MASM:
IF2
%OUT This is my message
ENDIF
IF2
.ERRNZ A NE B
ENDIF
; MASM 6.0:
ECHO This is my message
.ERRNZ A NE B <ASSERTION FAILURE: A NE B>
Generating an error if a symbol is not defined but may be forward referenced:
; PREVIOUS VERSIONS OF MASM:
IF2
.ERRNDEF var
ENDIF
; MASM 6.0:
.ERRNDEF var
See Section 1.3.3 for information on conditional directives.
Note:
In the following three cases, MASM 6.0 generates warnings if OPTION M510 is used.
IFDEF and IFNDEF with Forward-Referenced Identifiers
If you use a symbol name that has not yet been defined in an IFDEF or IFNDEF expression, MASM 6.0 returns FALSE for the IFDEF expression and TRUE for the IFNDEF expression. The assembler generates warning A5005:
IF condition may be pass-dependent
when OPTION M510 is enabled. To resolve the error, move the symbol definition to the beginning of the file.
The value of offsets calculated on the first assembly pass may not be the same as those calculated on later passes. Therefore, comparisons with a constant, such as the following, should be avoided:
IF OFFSET var1 - OFFSET var2 EQ 10
Note that expressions containing span distances can be used with the .ERR directives, since these directives are evaluated after all offsets are determined:
.ERRE OFFSET var1 - OFFSET var2 - 10, <span incorrect>
In MASM 5.1, .TYPE is evaluated on both assembly passes. This means it yields zero on the first pass and non-zero on the second pass if applied to an expression that forward references a symbol.
In MASM 6.0, .TYPE is evaluated on the first assembly pass. As a result, if the operand references a symbol that has not yet been defined, .TYPE will yield 0. This means that .TYPE, if used in a conditional-assembly construction, may yield different results with MASM 6.0 than with MASM 5.1.
This section lists features no longer supported by MASM 6.0. Because both of these items are obscure features provided by early versions of the assembler, they probably do not affect your MASM 5.1 code.
The ESC instruction, typically used to send hand-coded commands to the coprocessor, is no longer supported. Because MASM 6.0 recognizes and assembles the full set of coprocessor mnemonics, the ESC instruction is not necessary . Using the ESC instruction generates error A2205:
ESC instruction is obsolete: ignored
To update MASM 5.1 code, use the coprocessor instructions instead of ESC.
MASM 6.0 does not support the .MSFLOAT directive, which provided the Microsoft Binary Format (MSB) for floating-point numbers in variable initializers. Using the .MSFLOAT directive generates error A2204:
.MSFLOAT directive is obsolete: ignored
Use IEEE format or, if MSB format is necessary, initialize variables with hexadecimal values. See Section 6.1.2, “Storing Numbers in Floating-Point Format.”