README.DOC File
Release Notes for the Microsoft(R) Macro Assembler
Professional Development System, Version 6.0b
(C) Copyright Microsoft Corporation, 1992
This document contains release notes for version 6.0b of the
Microsoft Macro Assembler Professional Development System for
MS-DOS(R) and the Microsoft Operating System/2 (MS(R) OS/2). The
information in this document and in the Microsoft Advisor (online
help) is more up-to-date than that in the manuals.
Microsoft improves its languages documentation at the time of
reprinting, so some of the information in this file may already be
included in your manuals.
================================< Contents >================================
This file has 9 parts:
Part Contents
---- --------
1 Updated Files in MASM 6.0b
2 Assembler Update Notes
3 Information for MASM 5.1 Programmers
4 Notes on "Installing and Using"
5 Notes on "MASM 6.0 Reference"
6 Notes on "MASM 6.0 Programmer's Guide"
7 Using the DOS-Extended Assembler
8 Changes to CMACROS.INC
9 Known Assembler Bugs
======================< Part 1: Updated Files in MASM 6.0b >================
Changes
-------
Below is a list of the files that have changed in this release of
the Macro Assembler:
ML.EXE DOS-hosted assembler
ML.EXE OS/2-hosted assembler
ML.ERR Error text file for both DOS and OS/2 assemblers
MLX.EXE DOS-extended driver for DOS-hosted assembler
MASM.EXE MASM 5.1 compatibility driver
H2INC.EXE C header file to MASM include-file translator
H2INC.ERR Error text file for H2INC.EXE
CREF.EXE Source Browser based cross-reference utility. (NEW)
PROLOGUE.INC Predefined function prologues and epilogues
DOS.INC Predefined DOS function macros
CMACROS.INC C-styled assembly macros (MASM 5.1 compatible)
CMACROS.NEW Same as CMACROS.INC, but uses MASM 6.0 features (NEW)
BELL.C TSR example program
BELL.MAK TSR example program
SNAP.ASM TSR example program
QPEX.ASM QuickPascal mixed-language example
OS2.LIB OS/2 development libraries
API.LIB OS/2 development libraries
APILMR.OBJ OS/2 development libraries
SMARTDRV.EXE DOS-hosted disk caching software
SMARTDRV.DOC SMARTDRV.EXE Documentation
RAMDRIVE.SYS DOS-hosted memory resident disk emulator
HIMEM.SYS Memory expansion software
MOUSE.COM DOS-hosted mouse driver program
====================< Part 2: Assembler Update Notes > =====================
Corrections Made in MASM 6.0b
------------------------------
- The high-level CALL directive INVOKE can now be used as the
first statement of a procedure.
- MASM.EXE can now invoke MLX.EXE by using the /Q command-line
option. MASM.EXE still invokes ML.EXE when the /Q option is
not used.
- Code and data alignment problems are corrected.
- If the ALIGN directive was used with a value greater than
2, the bytes representing the instructions that were
generated for the padding (mov ax, ax) were reversed.
- If an ALIGN directive immediately followed any composite data
declaration (i.e. DUP, STRUCT, etc.) the results of the ALIGN
directive would be incorrect.
- Structure padding is now correct.
- Improvements were made to the MLX.EXE DOS Extender.
- Increased CodeView(R) information capacity is now available.
- COMM directive syntax corrections were made.
- ORG $ + X, where X is a constant, no longer effects ORG directives
found later in the source file.
- Miscellaneous problems in listing files are corrected.
Calling Convention Changes
--------------------------
Changes were made to the STDCALL calling convention after MASM 6.0
was shipped. These changes are reflected in MASM 6.0b. To maintain
the previous use of STDCALL, use the new OPTION directive:
OPTION OLDSTDCALL
Below is a chart describing all of the calling conventions found in
MASM 6.0b.
For the procedure func(a1,a2, ... an), the following chart
describes the results when used with the calling convention
found on the left side.
Responsible
for Stack Argument VARARG
Convention Name Cleanup Push Order Allowed
---------- ----- ----------- ------------- -------
C _func caller right-to-left Yes
BASIC FUNC callee left-to-right No
FORTRAN
PASCAL
SYSCALL func callee right-to-left Yes
STDCALL (16) _func@N callee left-to-right No
STDCALL (32) _func@N callee right-to-left No
OLDSTDCALL _func caller/callee* right-to-left Yes
STDCALL Naming Note
-------------------
In addition to the prefixed underscore, STDCALL also adds
the suffix, @N, where N is the total number of bytes that
will be pushed onto the stack.
Also, note that argument push order differs between
16-bit and 32-bit procedures.
*OLDSTDCALL
----------
The responsibility for cleaning the stack is always on the
callee, unless the procedure uses VARARG's, in which case
the caller is responsible for cleaning the stack.
CREF.EXE
--------
MASM 6.0 did not include the cross-reference CREF.EXE, because the
Programmer's Workbench included the Source Browser (a more full-featured
cross-reference utility). However, many MASM programmers need the
features available in CREF. To that end, we have included a new
release of CREF.EXE. This new CREF uses the same files that are used
by the Source Browser and produces reports very similar to those
created by previous releases.
For more information, read the text file CREF.DOC, located in
the same directory as CREF.EXE (default directory is \MASM600\BINB).
===============< Part 3: Information for MASM 5.1 Programmers >=============
"Quick Start" booklet
---------------------
If you have programs that assemble with previous versions of MASM,
this booklet will help you use MASM 6.0.
=================< Part 4: Notes on "Installing and Using" >================
Installation Program Notes
--------------------------
- Make sure that your TMP environment variable is set to a
fully qualified path (such as C:\TMP) before running SETUP.
- Use "SETUP /M" if you are using a monochrome display adapter
as your primary display.
- Under OS/2, if you are already running QuickHelp as a keyboard
monitor, disable it before running SETUP so that it can copy
new versions of QuickHelp and MSHELP.DLL to your hard disk.
Configuring Extended Memory for the CodeView Debugger
-----------------------------------------------------
When creating a .PIF file for CodeView, make sure you specify
the following command-line options:
Mode Option
---- ------
Real /d
Standard /d
Enhanced /d (or /e if expanded memory is available)
Page Note
---- ----
26 The file type indicator for MASM source code in Table 3.1
is incorrect. Rather than "ASM", the indicator should be
"MACRO".
56 The code fragment in the Section "Debugging HELLO.EXE", should
be:
MOV ah, 0ffh ;The register was ax, and is now ah
int 21h
==================< Part 5: Notes on "MASM 6.0 Reference" >=================
Page Note
---- ----
16 MASM /D Option
--------------
The /D Option is translated as follows:
/D Creates a Pass 1 listing. Translated to /Fl /Sf.
17 ML /VM Option
-------------
/VM Enables virtual memory under MS-DOS.
33 EXITM Directive
---------------
The EXITM directive takes an optional textitem, not an
expression.
152 XCHG Instruction
----------------
The second example line should be as follows:
xchg dl, dh
==============< Part 6: Notes on "MASM 6.0 Programmer's Guide" >============
Reserved Words
--------------
Add this paragraph to the description of reserved words in Section
1.21, "Reserved Words," and Appendix D, "MASM Reserved Words":
With the /Zm command-line option or OPTION M510, keywords and
instructions that are not available in the current CPU mode (such as
ENTER under .8086) are not treated as keywords. The USE32, FLAT, FAR32,
and NEAR32 segment types and the 80386/486 registers are not keywords
when using processor selection directives less than .386.
Structure Example
-----------------
Change the example in Section 3.2.4.1, "Indirect Operands with 16-
and 32-bit Registers" to read:
.
.
.
mov bx, OFFSET students
mov ax, 4
mov di, SIZE STUDENT
mul di
mov di, ax
mov al, (STUDENT PTR[bx+di]).year
Scaling Register Example
------------------------
Change this example line in Section 3.2.4.3, "Indirect Memory Operands
with 32-bit Registers":
mov eax,[ebp*2] ; EBP base (only - seg SS)
should be:
mov eax,[ebp*2] ; no base (scaled - seg DS)
Data Type Size
--------------
The data type table in Section 4.1.1, "Allocating Memory for Integer
Variables" should show that the size of a variable defined with the
DWORD or SDWORD initializer is 4 bytes.
Stack Variable Labels
---------------------
In Section 4.2.2.1, "Saving Operands on the Stack," brackets
are missing in the argument in the last sentence. Change
this paragraph:
If you use these stack values often in your program, you may
want to give them labels. For example, you can use TEXTEQU to
create a label such as "count TEXTEQU <bp-6>".
to this:
If you use these stack values often in your program, you may
want to give them labels. For example, you can use TEXTEQU to
create a label such as "count TEXTEQU <[bp-6]>".
ALIGN, EVEN, and ORG in Structures and Unions
---------------------------------------------
Add this paragraph to Section 5.2, "Structures and Unions":
The ALIGN, EVEN, and ORG directives can be used during structure
definition to modify how offsets of elements are defined. The EVEN
and ALIGN directives will round the current field offset up to the
specified align value by inserting padding bytes into the skipped
space. The ORG directive may be used to change the current field
offset to a new value, either positive or negative. If the ORG
directive is used in a structure definition, you cannot create an
instance of the structure.
Nested Structure Example
------------------------
Change this line in the first example of Section 5.2.2, "Defining
Structure and Union Variables":
ITYPE UNION
should be:
UNION ITYPE
Indirect Operands Example
-------------------------
In Section 7.1.1.2, "Indirect Operands," the line:
jmp ebx ; FAR32 jump
should be:
jmp ebx ; NEAR32 jump
Decision Directives Example
-------------------------
In Section 7.1.2.6, "Decision Directives," the line:
.IF cx = 20
should be:
.IF cx == 20
VARARG Example
--------------
In Section 7.3.3.3, "Using VARARG," the line:
dec arg1 ;Point to next argument
should be:
dec argcount ;Point to next argument
Indirect Procedure Invocation Example
-------------------------------------
Part of the first example in Section 7.3.7.5, "Invoking Procedures
Indirectly," is incorrect. Here is the corrected code:
.CODE
mov bx, pFunc ; pFunc is the function table
mov si, Num ; Num contains 0 or 2
INVOKE FUNCPTR PTR [bx+si], 1, 1 ; Selects proc1 or proc2
The sentence that says:
You can also use ASSUME to accomplish the same task. The ASSUME
statement associates the type PFUNC with the BX register.
should be:
You can also use ASSUME to accomplish the same task. In the
sample below, the ASSUME statement associates the type FUNCPTR
with the BX register.
In the example that follows, add the following line after the ASSUME:
mov bx, pFunc
Also, change the INVOKE line to read:
INVOKE [bx+si], 1, 1
DOS Interrupt Example
---------------------
In Section 7.4.1, "Calling DOS and ROM-BIOS Interrupts," the line:
msg BYTE "This writes to the screen",$
should be:
msg BYTE "This writes to the screen$"
DOS Interrupt Redefinition
--------------------------
In Section 7.4.2, "Replacing or Redefining Interrupt Routines,"
the numbers 25 and 35 should be replaced by 25h and 35h respectively.
In the following example, the line:
.MODEL LARGE, C, DOS
should be:
.MODEL LARGE, C, OS_DOS
EXTERNDEF Diagram
-----------------
In Figure 8.1, "Using EXTERNDEF for Variables," the line:
mov ax, array1[12]
should be:
mov al, array1[12]
Public and EXTERN Diagram
-------------------------
In Figure 8.3, "Using PUBLIC and EXTERN," the example file MOD2.ASM
should be:
.MODEL small, Pascal
EXTERN var:BYTE, BuildTable:NEAR
.CODE
.
.
.
mov al, Var
call BuildTable
EXTERN Library Example
----------------------
In Section 8.4.2, "Using EXTERN with Library Routines," the line:
EXTERN init(dummy)
should be:
EXTERN init(dummy):PROC
Expansion Operator (%)
----------------------
The last paragraph of Section 9.3.2.1, "The Expansion Operator with
Constants" is incorrect. Macro arguments cannot be expanded
constants alone; they must be enclosed in angle brackets (<>).
FOR Loops
---------
In Section 9.4.3, "FOR Loops and Variable-Length Parameters," the
line:
FOR arg, arglist
should be:
%FOR arg, arglist
SIZESTR Result
--------------
The description of the SIZESTR directive in Section 9.5, "String
Directives and Predefined Functions" should say that SIZESTR
assigns a numeric value, rather than a string.
String Directive Example
------------------------
In Section 9.5, "String Directives and Predefined Functions," the
RestoreRegs macro should be:
RestoreRegs MACRO
LOCAL regs
%FOR regs,regpushed ;;Pop each register
pop regs
ENDM
ENDM
PUSHCONTEXT/POPCONTEXT Table
----------------------------
The table in Section 9.7.2, "Testing for Argument Type and
Environment" should be as follows:
Option Description
------ -----------
ASSUMES Saves segment register information
LISTING Saves listing and CREF information
CPU Saves current CPU and processor
RADIX Saves current default radix
ALL All of the above
LINK Wildcards
--------------
In Section 10.3.1.5, "Wild Cards," the example description block
should be:
project.exe : *.obj
LINK $**;
New Anonymous Bit-Field Syntax
-----------------------------
Add these paragraphs to Section 16.3.5, "Bit Fields":
H2INC translates anonymous bit fields by padding with a tag
corresponding to the bit position.
For example,
struct s
{
int :8;
int j:8;
}
becomes:
s RECORD j@s:8,
@8@s:8
Basic/MASM Far Externs
----------------------
Add these paragraphs to Section 20.3.3, "The Basic/MASM Interface":
When interfacing with Basic, all EXTERNs that are far must be
declared outside of a code or data segment.
This is incorrect:
.MODEL medium
.CODE
EXTERN StringAddress:FAR
This is correct:
.MODEL medium
EXTERN StringAddress:FAR
.CODE
New Command-line Options
------------------------
Add these paragraphs to Appendix C, "Generating and Reading Assembly
Listings."
With the PAGE directive, the default page length is 0 (infinite), and
the default page width is 0 (infinite). The allowable value ranges are
0 and 60-255 for page width, 0 and 10-255 for page length.
With the /Sf option, a first-pass listing will be generated even if
a fatal error occurs. The symbol table will be appended onto the end
of the listing file unless you give the /Sn option.
The first-pass listing is controlled by the same set of commands that
are used with the final listing.
Additional Error Messages
-------------------------
Add these new or changed error messages to Appendix F, "Error
Messages":
MASM fatal error A1006
invalid command-line option: 'option'
ML did not recognize the given parameter as an option.
This error is generally caused when there is a syntax error on the
command line. It can also be generated by trying to assemble multiple
assembly-language files on the MLX driver command line.
MASM fatal error A1017
out of near memory
There was insufficient memory to assemble the program.
One of the following may be a solution:
- If you are using the NMAKE utility, try using NMK or
assembling outside of NMAKE.
- in PWB, try exiting and assembling using ML.
- In OS/2, try increasing the swap space.
- In DOS, remove terminate-and-stay-resident (TSR) software.
- If you have extended memory available, use the MLX.EXE driver.
- Change CONFIG.SYS to specify a lower number of buffers (the
BUFFERS= command) and fewer drives (the LASTDRIVE= command).
- Eliminate unnecessary INCLUDE directives.
MASM fatal error A1019
invocation failed : retry command line with /VM option
ML tried to restart itself with the /VM option but failed.
Enter the ML command line again, but add the /VM virtual-memory
option explicitly.
MASM error A2007
non-benign record redefinition
A RECORD definition conflicted with a previous definition.
One of the following occurred:
- There were different numbers of fields.
- There were different numbers of bits in a field.
- There was a different label.
- There were different initializers.
MASM error A2202
illegal use of segment register
You cannot use segment overrides for the FS or GS segment registers
when generating floating-point emulation instructions with the /FPi
command-line option or OPTION EMULATOR.
MASM error A2203
cannot declare scoped code label as PUBLIC
A code label defined with the "label:" syntax was declared PUBLIC.
Use the "label::" syntax, the LABEL directive, or OPTION NOSCOPED
to eliminate this error.
MASM error A2204
.MSFLOAT directive is obsolete : ignored
The Microsoft Binary Format is no longer supported.
You should convert your code to the IEEE numeric standard, which is
used in the 80x87-series coprocessors.
MASM error A2205
ESC instruction is obsolete : ignored
The ESC (Escape) instruction is no longer supported. All numeric
coprocessor instructions are now supported directly by the assembler.
MASM warning A4005
unknown default prologue argument
An unknown argument was passed to the default prologue.
The default prologue understands only the FORCEFRAME and LOADDS
arguments.
MASM warning A4013
line number information for segment without class 'CODE'
There were instructions in a segment that did not have a class
name that ends with "CODE". The assembler did not generate
CodeView information for these instructions.
CodeView cannot process modules with code in segments with
class names that do not end with "CODE".
MASM warning A4014
instructions and initialized data not supported in AT segments
An instruction or initialized data was found in a segment defined
with the AT attribute. The code or data will not be loaded at run
time.
Data in AT segments must be declared with the ? initializer.
MASM warning A4015
/VM ignored in Windows enhanced mode; use MLX.EXE for extra capacity
The /VM virtual memory command-line option was used explicitly or
implicitly inside an enhanced-mode DOS box. The /VM option was
ignored.
Use the MLX DOS-extended assembler to assemble large .ASM files
from a DOS box.
MASM warning A6004
procedure argument or local not referenced
You passed a procedure argument or created a variable with the LOCAL
directive that was not used in the procedure body.
Unnecessary parameters and locals waste code and stack space.
MASM warning A6005
IF condition may be pass-dependent
Under the /Zm command-line option or the OPTION M510 directive,
the value of an IF condition changed between passes.
This error message may indicate that the code is pass-dependent and
must be rewritten.
H2INC fatal error HI1801
incomplete model specification
Only part of a custom memory-model specification was specified on
the command line.
When you specify a custom memory model with the /A command-line
option, you must specify code pointer distance, data pointer distance,
and DS register setup. This error is equivalent to the D2013 error
message for CL.
=================< Part 7: Using the DOS-Extended Assembler >===============
MLX: The DOS-Extended Assembler
-------------------------------
There is a new DOS-extended driver for ML called MLX. MLX loads
ML.EXE into high memory so that the assembler takes up very little
space in the first 640K of memory.
MLX uses extended memory to run ML in protected mode. If you have
multiple extended memory drivers available, MLX will select the
driver to use in this order:
- DPMI
- VCPI
- XMS
The HIMEM.SYS XMS driver is included in the MASM 6.0 package and
is automatically copied by setup into the real-mode executables
directory as MLX.EXE. To use HIMEM.SYS, put the following line
into your CONFIG.SYS file:
DEVICE = <path>HIMEM.SYS
where <path> is the path to the location of HIMEM.SYS.
Use MLX only if running ML with the /VM virtual-memory option fails
due to an out-of-memory error. Because it runs in real mode, ML
with the /VM command-line option can run significantly faster than
MLX.
MLX Requirements
----------------
MLX requires an active DPMI, VCPI or XMS driver and at least 384K
of available extended memory to operate.
Differences between ML and MLX
------------------------------
The MLX DOS-extended driver can assemble only one source file at
a time. You must split multiple-file assemblies into several
invocations of MLX.
If you want to use MLX from the PWB command line, you must manually
change your makefile to reflect the name of the MLX driver. Change
the line:
ASM = ML
to:
ASM = MLX
MLX and EMM386.EXE
------------------
If you are using EMM386.EXE with the NOEMS option, the MLX driver
reports error R6921 - DOSX16 no expanded memory under VCPI host. To
use MLX with EMM386, replace "NOEMS" with "512 RAM". For example:
REM Old EMM386 statement
DEVICE=C:\WINDOWS\EMM386.EXE x=D800-DFFF noems
REM Replacement EMM386 statement
DEVICE=C:\WINDOWS\EMM386.EXE x=D800-DFFF 512 RAM
Note: The EMM386 options apply only if you are running MLX outside
of Windows. If you are running MLX in a Windows DOS Box, MLX uses
the Windows DPMI server.
======================< Part 8: Changes to CMACROS.INC >====================
Using CMACROS.INC
-----------------
There is a new MASM 6.0-compatible version of CMACROS.INC included
with the assembler. If you work with the Windows 3.0 Software
Development Kit, or the C 6.0 or FORTRAN 5.0 startup code, use the
new version of CMACROS.INC.
C and FORTRAN Startup Sources
-----------------------------
To build the C or FORTRAN startup sources, change the ASMFLAGS line
of MAKEFILE from:
ASMFLAGS= -Mx -Dmem_$(MODEL) -I$(INC)
to:
ASMFLAGS= -Mx -Dmem_$(MODEL) -I$(INC) -DMS_STARTUP
=====================< Part 9: Known Assembler Bugs >===================
Ambiguous Radix Characters
--------------------------
The assembler accepts numeric characters outside the range of the
current radix. These characters are given their appropriate
values but are handled under the current radix. For example,
.RADIX 10
mov ax, 1F
mov bx, 1Fh
loads ax with 25 (10 from the tens digit and 15 from the ones digit).
The bx register is loaded properly.
Structure Members with Decision Directives
------------------------------------------
When using pointers to structures in a decision directive (such as
.IF or .WHILE), you must simplify the expression with a type
definition. For example,
.WHILE (MyStruct PTR [bx]).Member1 != 4096
should be rewritten as:
StructPointer TYPEDEF PTR MyStruct
ASSUME BX:StructPointer
.
.
.
.WHILE [bx].Member1 != 4096
SIZEOF and LENGTHOF Operators with Structure Members
----------------------------------------------------
Expressions applying SIZEOF and LENGTHOF to structure members can
have problems when another SIZEOF or LENGTHOF expression follows.
There are two ways to avoid the error:
- Place the SIZEOF (or LENGTHOF) 'structmember' expression at the
end of the line.
- Separate the expression through the use of an equate.
The following example illustrates both the circumstances that can
cause this problem and the workaround:
.model small
.data
; Define a struct
;
MyStruct struct
aa byte ?
bb byte ?
MyStruct ends
xx db ?
yy db ?
cMyStruct equ sizeof MyStruct.aa
.code
; problem cases
mov al,sizeof MyStruct.aa + sizeof yy
mov al,sizeof MyStruct.aa + sizeof MyStruct.bb
; solution cases
mov al,sizeof yy + sizeof MyStruct.aa
mov al,cMyStruct + sizeof MyStruct.bb
end
The solution cases are rewrites of the problem cases. The first
solution works because SIZEOF appears at the end of the line. The
second solution is a case where the size of two structure members
must be obtained, precluding the first kind of solution. In such a
case, use an equate for all but the last SIZEOF or LENGTHOF in the
expression.
Address Spans as Constants
--------------------------
Offset calculations may differ between passes, so comparisons with
constants should be avoided. For more information, see Section
A.2.1.3, "Code Requiring Two-Pass Assembly," in the Programmer's
Guide manual.
Virtual-Memory Assembly in a Windows DOS box
--------------------------------------------
The /VM virtual memory command-line option is not allowed when
running in a Windows enhanced-mode DOS box. Use MLX.EXE if you
need more assembler capacity.