|
*LEGAL DISCLAIMER: All references to Microsoft products, including but not
limited to: Microsoft Macro Assembler (MASM), MS-DOS, Visual C++, Visual Basic,
Visual Studio, Windows, Windows NT, Windows Software Development Kit (SDK) and
associated logos or images are trademarks owned and copyright by Microsoft
Corporation.
Microsoft MASM was originally an assembler (i.e. assembly language compiler) for the Intel 8086 processor
targeting IBM PC and compatible computers. This processor and its successors were grouped into what
eventually became known as Intel's x86 architecture, capable of targeting 16-bit (286 and below) and 32-bit
(386 and up) modes. Around 2005, Microsoft released a 64-bit version of MASM targeting AMD's 64-bit
specification (now known as the x64 architecture), which is a 64-bit extension to the x86 line of
processors. Microsoft publicly released this assembler alongside the x64 debut releases of Windows: XP and
Server 2003. Although Microsoft has publicly released an assembler for ARM processors (known as ARMASM) at
least as of Visual Studio 2013, it is technically not MASM. The primary focus of this page are the x86 and
x64 versions of MASM.
Before Microsoft's Macro Assembler popularized the acronym MASM, MASM previously meant Meta Assembler
(essentially an assembler-generation tool whose application is primarily used in mainframe computing).
In the pre-DOS era, there were many macro-style assemblers produced by different companies, primarily
targeting mainframes or the newly emerging proprietary chipsets for personal computers or gaming systems.
During this time, someone invented the notion of a “macro”, which is essentially a series of
keystrokes assigned to a name or keyboard sequence as a time saving construct. In these days, macro support
was popular and used in many utilities from spreadsheets to command line shells, not just programming
languages. This was at a time where the major programming languages in widespread use today were still
under development, so it was common for entire applications to be written purely in assembly language. As
programming in assembly language is just one small step above programming directly in machine language
(programming in numeric codes), it takes many separate instructions to perform even the most simple tasks
such as writing a single character to a display terminal. This is why assembly language is known as a
tedious programming language.
When used in assembly language, macros enable
programmers to assign a group of commonly used instructions to a name and insert those instructions anywhere
the name appears in as many places as that common task is needed. Microsoft's Macro
Assembler (MASM), initially appearing in 1981 near the release of Microsoft's IBM PC-DOS, is an assembler
using the Intel syntax/notation. MASM became the most popular assembler likely due to the success of DOS
and Windows. As of this writing, MASM is the oldest IBM PC assembler still being actively developed and
supported.
Origins of MASM:
After some guesswork as to the origins of MASM being possibly related to the 8086 Assembler created by
Tim Paterson of SCP (Seattle Computer Products), I was able to contact him for his help in clearing things up.
Tim Patterson, the original creator of DOS and the famous
DEBUG.COM, wrote an
8086 assembler (ASM) to assemble 86-DOS, the predecessor to MS-DOS.
Here is what he said:
MASM was written in Pascal by Marc McDonald (Microsoft employee #1, after Bill & Paul).
Microsoft had been doing all their development on DEC computers, and the macro capability put in MASM was
modeled after DEC assemblers. Because MASM was such a large macro assembler, one of the guys referred to it as
"McDonald's big mac".
...
MASM does not have lineage back to M80. It was written specifically for the 8086 and attempted some level of
compatibility with Intel's 8086 assembler. I remember it was different from what I was used to. When MS bought
DOS from SCP I was at MS. After finishing up DOS 1.0, I translated DOS from SCP's assembler to MASM, and I
needed Marc to explain some of the syntax to me.
He also had the following to say about his 8086 Assembler he wrote while at SCP:
The 8086 assembler I wrote originally was in Z80 assembly language and ran under CP/M. I believe it was
distributed with the SCP 8086 CPU card as ASM86. I also wrote a translator that converted Z80 source
code to inefficient but workable 8086 source code (Intel promoted this idea with a published translation
table). This was called TRANS86 and was also written in Z80 assembly for CP/M. Once DOS was working, I
applied the translator to ASM86 (and to itself) to create 8086 versions that ran under DOS. I do not
have the change history in front of me (I see you deleted it from your history page), but I believe that
versions >= 2 marked the translated (DOS) version. If any history shows version numbers < 2, that was
the CP/M version.
Although the SCP 8086 Assembler was used to build early versions of DOS (86-DOS, MS-DOS 1.x), Microsoft's
major rewrite of DOS 2.0 included changing the build system to use Microsoft's own assembler, MASM. More
information about Tim's 8086 Assembler (ASM) can be found at the Computer History Museum's
Microsoft
MS-DOS early source code article. From here you may download the now freely available MS-DOS 1.1 and 2.0
source code which includes the source code to Tim's 8086 Assembler and the Z80 to 8086 translator.
Evolution of MASM:
From MASM 1.0 in 1981 (corresponding to the release of MS-DOS 1.0), MASM enjoyed almost 13 years as a
distinct Microsoft product. This status was lost with MASM version 6.11 in 1993 where Microsoft stated MASM
is no longer available as a retail product. With the popularity of the new and various programming
languages available, the demand for people wanting to write in pure assembler declined, so Microsoft
followed suit and downgraded MASM to a system-level C/C++ tool. Microsoft would release patches for new
versions of MASM (primarily to accommodate changes in Intel's upcoming chipsets) up to version 6.14 in 1999.
In the year 2000, the Microsoft released MASM 6.15, not as a patch, but as an add-on to Visual C++ 6.0 and
no official changelist was officially published. Since version 6.15, MASM has been bundled with every
release of Visual C++ via Microsoft Visual Studio to date along with the rest of the C/C++ toolset.
Microsoft's first failure in documentation was a lack of an official changelist for MASM version 6.15,
something they had dutifully adhered to up until this point. Unfortunately version 6.15 was one of the most
stable and widely used versions, not to mention one of the most historically significant. This version had
finally stabilized all of the 6.xx features (started 9 years prior) with the recently solidified
architecture of the now-dominant Win32 platform ala Windows NT and Windows 9x. The 6.xx features were the
only real thing that set MASM apart from Borland's Turbo Assembler which was the market leader in MASM 5.xx
syntax. I spent a good deal of time scouring the internet for changelist information for this version and I
found nothing but unofficial tidbits. Once I had put together an unofficial 6.15 changelist, this soon grew
to encompass all 6.xx versions. Eventually this page was born as the changelist quickly expanded to all
known versions of MASM.
I have attempted obtain the most complete version information for Microsoft's MASM throughout its history
using official information when available and falling back to bits and pieces from other sources when
information is limited. This includes printed manuals, readme's and other information shipping with the
product, MSDN content, or other Microsoft websites. When appropriate, opinions and hearsay are also
included (and noted as such), as this helps develop a clearer picture of how the product impacted those
who used it, circumventing the usual marketing rhetoric from official sources.
Version | Copyright | Runs Under | Main Program Date/File/Size | @Version | Build Version |
MACRO-80 | 1979 | CPM | 12/09/1981 | M80.COM | 20 k | | 3.4 |
MACRO-86 | 1981 | DOS | | M86.EXE | | | |
MASM 1.0 IBM | 1981 | DOS | 12/07/1981 10:00pm | MASM.EXE | 66 k | | |
MASM 1.0 | 1981 | DOS | 02/05/1982 12:49pm | M.EXE | 66 k | | |
MASM 1.06 | 1982 | DOS | 02/08/1982 | MASM.EXE | 69 k | | |
MASM 1.10 | 1982 | DOS | 02/01/1983 01:13pm | MASM.EXE | 76 k | | |
MASM 1.25 | 1983 | DOS | 08/25/1982 | MASM.EXE | 79 k | | |
MASM 1.27 | 1984 | DOS | 11/27/1984 09:25am | MASM.EXE | 79 k | | |
MASM 2.0 IBM | 1984 | DOS | 07/18/1984 12:01pm | MASM.EXE | 75 k | | |
MASM 2.04 | 1982 | DOS | 03/02/1982 | MASM.EXE | 66 k | | |
MASM 3.0 | 1984 | DOS | 11/21/1984 02:49pm | MASM.EXE | 76 k | | |
MASM 3.01 | 1984 | DOS | 11/21/1984 02:49pm | MASM.EXE | 76 k | | |
MASM 4.0 | 1985 | DOS | 10/16/1985 04:00am | MASM.EXE | 84 k | | |
MASM 4.01 | 1985 | DOS | 07/24/1987 12:00am | MASM401.EXE | 100 k | | |
MASM 5.0 | 1987 | DOS | 07/31/1987 12:00am | MASM.EXE | 101 k | | |
MASM/2 1.0 IBM | 1987 | OS/2,DOS | 09/03/1987 04:00pm | MASM.EXE | 112 k | | |
MASM 5.10 | 1988 | DOS,OS/2 | 02/01/1988 01:00pm | MASM.EXE | 108 k | 510 | |
MASM 5.10A | 1989 | DOS,OS/2 | 01/16/1989 11:10am | MASM.EXE | 108 k | 510 | |
MASM 5.10B | 1989 | DOS,OS/2 | 01/04/1992 12:52pm | MASM5.EXE | 109 k | 510 | |
QuickAssembler | 1990 | DOS | | | | | |
MASM386 5.NT.02 | 1989 | WIN32 | 11/01/1993 06:28am | MASM386.EXE | 207 k | 510 | 3.10.508.1 |
MASM 6.0 | 1991 | DOS,OS/2 | 04/03/1991 02:59pm | ML.EXE | 239 k | 600 | |
MASM 6.00A | | | | | | | |
MASM 6.00B | 1992 | DOS,OS/2 | 03/18/1992 05:31pm | ML.EXE | 244 k | 600 | |
MASM 6.1 | 1992 | DOS,WIN32 | 11/16/1992 04:00pm | ML.EXE | 352 k | 610 | |
MASM 6.1a | 1992 | DOS,WIN32 | 03/12/1993 01:59pm | ML.EXE | 353 k | 610 | |
MASM 6.11 | 1993 | DOS,WIN32 | 09/24/1993 08:25am | ML.EXE | 380 k | 611 | |
MASM 6.11a | 1994 | DOS,WIN32 | 03/21/1994 12:22pm | ML.EXE | 374 k | 611 | |
MASM 6.11c | 1994 | DOS,WIN32 | 08/25/1994 06:30pm | ML.EXE | 373 k | 611 | |
MASM 6.11d | 1995 | DOS,WIN32 | 09/19/1995 01:18pm | ML.EXE | 379 k | 611 | |
MASM 6.12 | 1997 | WIN32 | 08/27/1997 03:49pm | ML.EXE | 358 k | 612 | 6.12.7164 |
MASM 6.13 | 1997 | WIN32 | 12/05/1997 01:43pm | ML.EXE | 344 k | 613 | 6.13.7299 |
MASM 6.14 | 1997 | WIN32 | 04/12/1999 03:05pm | ML.EXE | 364 k | 614 | 6.14.8444 |
MASM 6.15 | 2000 | WIN32 | 03/16/2000 03:20pm | ml.exe | 376 k | 615 | 6.15.8803 |
MASM 7.0 | | WIN32 | 01/05/2002 03:36am | ml.exe | 404 k | 615 | 7.00.9466 / VS.NET 2002 7.0 (any*) |
MASM 7.1 | | WIN32 | 07/11/2006 06:15pm | ml.exe | 404 k | 710 | 7.10.6030 / VS.NET 2003 PRO 7.1 |
MASM 8.0 | | WIN32/64 | 04/21/2006 06:11pm | ml.exe | 342 k | 800 | 8.00.50727.104 / VS 2005 8.0 EXPRESS, PRO & ACADEMIC |
MASM 9.0 | | WIN32/64 | 07/30/2008 12:05pm | ml.exe | 353 k | 900 | 9.00.30729.01 / VS 2008 9.0 (any*) / Win32 |
MASM 10.0 | | WIN32/64 | 03/19/2010 02:02pm | ml.exe | 388 k | 1000 | 10.00.30319.01 / Win32 |
MASM 11.0 | | WIN32/64 | 07/26/2012 07:08pm | ml.exe | 424 k | 1100 | 11.00.50727.1 / Win32 |
MASM 12.0 | | WIN32/64 | 10/05/2013 02:38am | ml.exe | 429 k | 1200 | 12.00.21005.1 / From VS 2013 Express for Desktop / Win32 |
MASM 14.0 | | WIN32/64 | 06/25/2015 11:34pm | ml.exe | 436 k | 1400 | 14.00.23026.0 / From VS 2015 Community 14.0.23107.0 D14REL / Win32 |
MASM 14.1 | | WIN32/64 | 07/21/2017 05:22pm | ml.exe | 438 k | 1410 | 14.10.25019.0 / From VS 2017 Community |
Special thanks to Vernon from
pcdosretro
for sending the version information up to 6.14 in the tables shown below.
Vernon also extracted the
MASM 6.0B QuickHelp Documentation into a single text file for
quick reference and simple search lookups for the various MASM keywords and operators.
Despite being derived from the version 6.00B documentation, the majority of the information still applies to
current versions of MASM.
* NOTE: It is to be expected many characters in this file will not display as intended through your web
browser, specifically the high-ASCII line drawing characters. If you save the page as a text file and open it
in a command prompt under Windows (using "edit", "more" or any other text editor), the
high-ASCII characters will display as intended.
Keyword | Version |
BYTE | 5.0 |
DB | |
DD | |
DF | 5.0 |
DQ | |
DT | |
DW | |
DWORD | 5.0 |
ENDS | |
FWORD | 5.0 |
MMWORD | 8.0 |
OWORD | 6.14 |
QWORD | 5.0 |
REAL10 | 6.0 |
REAL4 | 6.0 |
REAL8 | 6.0 |
RECORD | |
SBYTE | 6.0 |
SDWORD | 6.0 |
SQWORD | 8.0 |
STRUC | |
STRUCT | 6.0 |
SWORD | 6.0 |
TBYTE | 5.0 |
TYPEDEF | 6.0 |
UNION | 6.0 |
WORD | 5.0 |
XMMWORD | 8.0 |
YMMWORD | 10.0 |
|
Keyword | Version |
.186 | 2.0-9.0 |
.286 | 5.0-9.0 |
.286C | 2.0-9.0 |
.286P | 3.0-9.0 |
.287 | 2.0-9.0 |
.386 | 5.0 |
.386C | 5.0 |
.386P | 5.0 |
.387 | 5.0 |
.486 | 6.0 |
.486P | 6.0 |
.586 | 6.11 |
.586P | 6.11 |
.686 | 6.12 |
.686P | 6.12 |
.8086 | 2.0-9.0 |
.8087 | 2.0-9.0 |
.K3D | 6.13 |
.MMX | 6.12 |
.NO87 | 6.0-9.0 |
.XMM | 6.14 |
|
Keyword | Version |
ALIGN | 5.0 |
.ALPHA | 5.0 |
ASSUME | |
.CODE | 5.0 |
.CONST | 5.0 |
.DATA | 5.0 |
.DATA? | 5.0 |
DOSSEG | 5.0 |
.DOSSEG | 6.0 |
END | |
ENDS | |
EVEN | |
.EXIT | 6.0 |
.FARDATA | 5.0 |
.FARDATA? | 5.0 |
GROUP | |
LABEL | |
.MODEL | 5.0 |
ORG | |
SEGMENT | |
.SEQ | 5.0 |
.STACK | 5.0 |
.STARTUP | 6.0 |
|
Keyword | Version |
.ALLOCSTACK (x64) | 8.0 |
ENDM | |
ENDP | |
.ENDPROLOG (x64) | 8.0 |
EXITM | |
.FPO | 5.10.NT, 6.11A, 8.0 |
GOTO | 6.0 |
INVOKE | 6.0 |
LOCAL | |
MACRO | |
PROC | |
PROTO | 6.0 |
PURGE | |
.PUSHFRAME (x64) | 8.0 |
.PUSHREG (x64) | 8.0 |
.SAFESEH | 7.1 |
.SAVEREG (x64) | 8.0 |
.SAVEXMM128 (x64) | 8.0 |
.SETFRAME (x64) | 8.0 |
USES | 5.10 |
|
Keyword | Version |
ALIAS | 6.11 |
COMM | 5.0 |
COMMENT | |
EXTERN | 6.0 |
EXTERNDEF | 6.0 |
EXTRN | |
INCLUDE | |
INCLUDELIB | 6.0 |
NAME | <=4.0 / ignored 5.0+ |
PUBLIC | |
|
Keyword | Version |
ECHO | 6.0 |
.MSFLOAT | 5.0 |
OPTION | 6.0 |
%OUT | |
POPCONTEXT | 6.0 |
PUSHCONTEXT | 6.0 |
.RADIX | |
|
Keyword | Version |
CATSTR | 5.10 |
INSTR | 5.10 |
SIZESTR | 5.10 |
SUBSTR | 5.10 |
|
Keyword | Version |
= | |
EQU | |
TEXTEQU | 6.0 |
|
Keyword | Version |
ENDM | |
FOR | 6.0 |
FORC | 6.0 |
GOTO | 6.0 |
IRP | |
IRPC | |
REPEAT | 6.0 |
REPT | |
WHILE | 6.0 |
|
Keyword | Version |
ELSE | |
ELSEIF | 5.10 |
ELSEIF1 | 5.10 |
ELSEIF2 | 5.10 |
ELSEIFB | 5.10 |
ELSEIFDEF | 5.10 |
ELSEIFDIF | 5.10 |
ELSEIFDIFI | 5.10 |
ELSEIFE | 5.10 |
ELSEIFIDN | 5.10 |
ELSEIFIDNI | 5.10 |
ENDIF | |
IF | |
IF1 | |
IF2 | |
IFB | |
IFDEF | |
IFDIF | |
IFDIFI | 5.0 |
IFE | |
IFIDN | |
IFIDNI | 5.0 |
IFNB | |
IFNDEF | |
|
Keyword | Version |
.BREAK | 6.0 |
.CONTINUE | 6.0 |
.ELSE | 6.0 |
.ELSEIF | 6.0 |
.ENDIF | 6.0 |
.ENDW | 6.0 |
.IF | 6.0 |
.REPEAT | 6.0 |
.UNTIL | 6.0 |
.UNTILCXZ | 6.0 |
.WHILE | 6.0 |
|
Keyword | Version |
.ERR | 4.0 |
.ERR1 | 4.0 |
.ERR2 | 4.0 |
.ERRB | 4.0 |
.ERRDEF | 4.0 |
.ERRDIF | 4.0 |
.ERRDIFI | 5.0 |
.ERRE | 4.0 |
.ERRIDN | 4.0 |
.ERRIDNI | 5.0 |
.ERRNB | 4.0 |
.ERRNDEF | 4.0 |
.ERRNZ | 4.0 |
|
Keyword | Version |
.CREF | |
.LALL | |
.LFCOND | |
.LIST | |
.LISTALL | 6.0 |
.LISTIF | 6.0 |
.LISTMACRO | 6.0 |
.LISTMACROALL | 6.0 |
.NOCREF | 6.0 |
.NOLIST | 6.0 |
.NOLISTIF | 6.0 |
.NOLISTMACRO | 6.0 |
PAGE | |
.SALL | |
.SFCOND | |
SUBTITLE | 6.0 |
SUBTTL | 5.10 |
.TFCOND | |
TITLE | |
.XALL | |
.XCREF | 5.10 |
.XLIST | 5.10 |
|
Keyword | Version |
@code | 5.0 |
@CodeSize | 5.0 |
@CurSeg | 5.0 |
@data | 5.0 |
@DataSize | 5.0 |
@fardata | 5.0 |
@fardata? | 5.0 |
@Model | 6.0 |
@stack | 6.0 |
@WordSize | 5.10 |
|
Keyword | Version |
@Cpu | 5.10 |
@Date | 6.0 |
@Environ | 6.0 |
@FileCur | 6.0 |
@FileName | 5.0 |
@Interface | 6.0 |
@Line | 6.0 |
@Time | 6.0 |
@Version | 5.10 |
|
Keyword | Version |
@CatStr | 6.0 |
@InStr | 6.0 |
@SizeStr | 6.0 |
@SubStr | 6.0 |
|
Keyword | Version |
$ | |
? | |
@@ | 5.10 |
@B | 5.10 |
@F | 5.10 |
|
Keyword | Version |
. | |
ABS | |
FAR | |
HIGH | |
HIGH32 | 8.0 |
HIGHWORD | 6.0 |
LENGTH | |
LENGTHOF | 6.0 |
LOW | |
LOW32 | 8.0 |
LOWWORD | 6.0 |
MASK | |
NEAR | |
OPATTR | 6.0 |
PTR | |
SHORT | |
SIZE | |
SIZEOF | 6.0 |
THIS | |
TYPE | |
.TYPE | |
WIDTH | |
|
Keyword | Version |
: | |
ADDR | 6.0 |
AT | |
BYTE | |
COMMON | |
DWORD | |
FLAT | 6.0 |
IMAGEREL | 8.0 |
LROFFSET | 6.0 |
MEMORY | |
OFFSET | |
PAGE | |
PARA | |
PRIVATE | 6.0 |
PUBLIC | |
SECTIONREL | 8.0 |
SEG | |
STACK | |
USE16 | 5.0 |
USE32 | 5.0 |
WORD | |
|
Keyword | Version |
" | |
"" | |
() | |
: | |
:: | 5.10 |
; | |
[] | |
CARRY? | 6.0 |
DUP | |
OVERFLOW? | 6.0 |
PARITY? | 6.0 |
SIGN? | 6.0 |
ZERO? | 6.0 |
|
Keyword | Version |
* | |
+ | |
. | |
/ | |
MOD | |
|
Keyword | Version |
! | |
!= | |
& | |
&& | |
< | |
<= | |
== | |
> | |
>= | |
|| | |
|
Keyword | Version |
EQ | |
GE | |
GT | |
LE | |
LT | |
NE | |
|
Keyword | Version |
AND | |
NOT | |
OR | |
SHL | |
SHR | |
XOR | |
|
Keyword | Version |
! | |
% | |
& | |
;; | |
<> | |
|
Keyword | Version |
BASIC | 5.10 |
C | 5.10 |
FORTRAN | 5.10 |
PASCAL | 5.10 |
STDCALL | 6.00B |
SYSCALL | 6.0 |
|
Keyword | Version |
COMPACT | 5.0 |
FLAT | 6.0 |
HUGE | 5.0 |
LARGE | 5.0 |
MEDIUM | 5.0 |
SMALL | 5.0 |
TINY | 6.0 |
|
Keyword | Version |
AH | |
AL | |
AX | |
BH | |
BL | |
BP | |
BX | |
CH | |
CL | |
CR0 | 5.0 |
CR2 | 5.0 |
CR3 | 5.0 |
CR4 | 5.0 |
CS | |
CX | |
DH | |
DI | |
DL | |
DR0 | 5.0 |
DR1 | 5.0 |
DR2 | 5.0 |
DR3 | 5.0 |
DR6 | 5.0 |
DR7 | 5.0 |
DS | |
DX | |
EAX | 5.0 |
EBP | 5.0 |
EBX | 5.0 |
ECX | 5.0 |
EDI | 5.0 |
EDX | 5.0 |
ES | |
ESI | 5.0 |
ESP | 5.0 |
FS | 5.0 |
GS | 5.0 |
MM0 | 6.12 |
MM1 | 6.12 |
MM2 | 6.12 |
MM3 | 6.12 |
MM4 | 6.12 |
MM5 | 6.12 |
MM6 | 6.12 |
MM7 | 6.12 |
SI | |
SP | |
SS | |
ST | |
TR3 | 5.0 |
TR4 | 5.0 |
TR5 | 5.0 |
TR6 | 5.0 |
TR7 | 5.0 |
XMM0 | 6.14 |
XMM1 | 6.14 |
XMM2 | 6.14 |
XMM3 | 6.14 |
XMM4 | 6.14 |
XMM5 | 6.14 |
XMM6 | 6.14 |
XMM7 | 6.14 |
YMM0 | 10.0 |
YMM1 | 10.0 |
YMM2 | 10.0 |
YMM3 | 10.0 |
YMM4 | 10.0 |
YMM5 | 10.0 |
YMM6 | 10.0 |
YMM7 | 10.0 |
|
Keyword | Version |
$ | |
? | |
ADDR | 6.0 |
@B | 5.10 |
BASIC | |
BYTE | |
C | |
CARRY? | 6.0 |
DWORD | |
@F | 5.10 |
FAR | |
FAR16 | 6.0 |
FAR32 | 6.0 |
FORTRAN | |
FWORD | |
NEAR | |
NEAR16 | 6.0 |
NEAR32 | 6.0 |
OVERFLOW? | 6.0 |
PARITY? | 6.0 |
SIGN? | 6.0 |
STDCALL | 6.00B |
SWORD | 6.0 |
SYSCALL | 6.0 |
TBYTE | |
VARARG | 6.0 |
WORD | |
ZERO? | 6.0 |
|
Keyword | Version |
ABS | |
ALL | |
ASSUMES | 6.0 |
AT | |
CASEMAP | 6.0 |
COMMON | |
COMPACT | 5.0 |
CPU | 6.0 |
DOTNAME | 6.0 |
EMULATOR | 6.0 |
EPILOGUE | 6.0 |
ERROR | 6.0 |
EXPORT | 6.0 |
EXPR16 | 6.0 |
EXPR32 | 6.0 |
FARSTACK | 6.0 |
FLAT | 6.0 |
FORCEFRAME | 6.0 |
HUGE | 5.0 |
LANGUAGE | 6.0 |
LARGE | 5.0 |
LISTING | 6.0 |
LJMP | 6.0 |
LOADDS | 6.0 |
M510 | 6.0 |
MEDIUM | 5.0 |
MEMORY | |
NEARSTACK | 6.0 |
NODOTNAME | 6.0 |
NOEMULATOR | 6.0 |
NOKEYWORD | 6.0 |
NOLJMP | 6.0 |
NOM510 | 6.0 |
NONE | |
NONUNIQUE | 6.0 |
NOOLDMACROS | 6.0 |
NOOLDSTRUCTS | 6.0 |
NOREADONLY | 6.0 |
NOSCOPED | 6.0 |
NOSIGNEXTEND | 6.0 |
NOTHING | |
NOTPUBLIC | 6.0 |
OLDMACROS | 6.0 |
OLDSTDCALL | 6.00B |
OLDSTRUCTS | 6.0 |
OS_DOS | 6.0 |
PARA | |
PRIVATE | 6.0 |
PROLOGUE | 6.0 |
RADIX | 6.0 |
READONLY | 6.0 |
REQ | 6.0 |
SCOPED | 6.0 |
SETIF2 | 6.0 |
SMALL | 5.0 |
STACK | |
TINY | 6.0 |
USE16 | 5.0 |
USE32 | 5.0 |
USES | |
|
|
M80.COM | 20,096 bytes (20k) | md5=cb37415442c76354003024e3a7cdeff3 | date=12/9/1981 | build 3.4 | (time of day from file stamp unknown) | |
M80.COM | 19,200 bytes (19k) | md5=19c63f05a7541b95ff28249e6c913448 | | build 3.4 | (file date unknown) | |
|
Retail Price: $200.00
The original Microsoft assembler product was for the 8080 Intel archtecture typically running the CP/M
operating system, predating DOS. Although Tim Paterson (creator of DOS) confirmed with me that MASM did not
originate from MACRO-80, it is included here for historical purposes as it appears to have been Microsoft's
first commercial assembler product.
According to
EMSPS, the list price was $200.
The
Intel 8080 Wikipedia Page
describes the 8-bit 8080 2 MHz microprocessor released in April 1974 as follows:
"The 8080 has sometimes been labeled "the first truly usable microprocessor", although earlier microprocessors
were used for calculators, cash registers, computer terminals, industrial robots and other applications. The
architecture of the 8080 strongly influenced Intel's 8086 CPU architecture, which spawned the x86 family of
processors."
The following snippet is from the
TRS-80 Manual: Macro-80
Assembler Introduction:
"MACRO-80 is a relocatable macro assembler for the 8080 and Z80 microcomputer systems. It assembles 8080 or Z80
code on any 8080 or Z80 development system running the CP/M, ISIS-II, TRSDOS or TEKDOS operating system. The
MACRO-80 package includes the MACRO-80 assembler, the LINK-*) linking loader, and the CRED-80 cross reference
facility. CP/M versions also include the LIB-80 Library Manager. MACRO-80 resides in approximately 14K of memory
and has an assembly rate of over 1000 lines per minute.
MACRO-80 incorporates almost all "big computer" assembler features without sacrificing speed or memory space.
The assembler supports a complete, Intel standard macro facility, including IRP, IRPC, REPEAT, local variables
and EXITM. Nesting of macros is limited only by memory. Code is assembled in relocatable modules that are
manipulated with the flexible linking loader. Conditional assembly capability is enhanced by an expanded set of
conditional pseudo operations that include testing of assembly pass, symbol definition, and parameters to
macros. Conditionals may be nested up to 255 levels."
Microsoft's next assembler (a two-pass assembler) targeted the 8086, a 16-bit microprocessor released by Intel in 1978. This was the
first in the series of microprocessors that later became known as the x86 architecture.
This was the first Microsoft assembler product for the 8086 architecture.
Microsoft's assembler (and main product line) has remained with this architecture to date.
Later versions of the assembler would be renamed to "Microsoft MACRO Assembler".
The manual states, "MACRO-86 supports most of the directives found in Microsoft's MACRO-80 Macro
Assembler. Macros and conditionals are Intel 8080 standard."
The
Microsoft
Utility Software Package Reference Manual for 8086 Microprocessors was the primary source for the information shown
below.
MACRO-86 was distributed on a single disk along with 4 files:
M86.EXE, LINK.EXE, LIB.EXE and CREF.EXE.
SYSTEM REQUIREMENTS:
MACRO-86 - 96K bytes of memory minimum:
64K bytes for code and static data
32K bytes for run space
MS-LINK - 54K bytes of memory minimum:
44K bytes for code
10K bytes for run space
MS-LIB - 38K bytes of memory minimum:
28K bytes for code
10K bytes for run space
MS-CREF - 24K bytes of memory minimum:
14K bytes for code
10K bytes for run space
1 disk drive
1 disk drive if and only if output is sent to the
same physical diskette from which the input was
taken. None of the utility programs in this
package allow time to swap diskettes during
operation on a one-drive configuration. Therefore,
two disk drives is a more practical configuration.
MASM.EXE | 67,584 bytes (66k) | md5=0c68bde13bf46f813b41fc5b19ed56d8 | date=12/7/1981 10:00pm | | | |
|
This was an IBM-branded OEM version of MASM developed by Microsoft specifically for the IBM PC, executing only
8086 instructions.
Detect It Easy identifies this version as being built with "IBM PC Pascal".
Vernon from
pcdosretro
says this version of MASM supports ESC and an archaic syntax which could be used to specify floating-point
opcodes.
The command line displays "The IBM Personal Computer MACRO Assembler" rather than the
"The Microsoft MACRO Assembler" displayed by the unbranded Microsoft version.
It is not known how much this version differs from the unbranded version although if the file dates we
have are correct, the IBM version pre-dates the unbranded version by just about 2 months.
Embedded within MASM.EXE at offset 0xE50D (58637) is the date string:
"8/24/81 Ver"
This may be a possible build timestamp. Although I don't have documentation on this version of MASM, I suspect
you can get the program to emit this string one way or another (via the command line or possibly using a
predefined macro combined with the old %out directive during assembly). This version date string is not
displayed on the command line when MASM is run with no options, but instead the copyright year of 1981.
The IBM versions of MASM also distributed a small companion assembler named ASM.EXE. This assembler
lacked some of the features present in MASM.EXE (such as the ability to use macros) so it would run
in PCs with only 64k of memory.
The original distribution contains the following directory list of 14 files, on a 160K 5¼ inch floppy disk:
09/24/1981 10:00 PM 137 $$EDASM.BAT
09/24/1981 10:00 PM 140 $$EDMASM.BAT
10/28/1981 10:00 PM 622 $ASML.BAT
10/28/1981 10:00 PM 614 $EDASM.BAT
10/28/1981 10:00 PM 614 $EDMASM.BAT
09/24/1981 10:00 PM 23 $LINK.ARF
10/28/1981 10:00 PM 615 $MASML.BAT
12/07/1981 10:00 PM 52,736 ASM.EXE
10/04/1981 10:00 PM 13,824 CREF.EXE
11/08/1981 10:00 PM 6,580 EXMP1M.ASM
11/08/1981 10:00 PM 5,621 EXMP1S.ASM
09/15/1981 10:00 PM 2,015 EXMP2M.ASM
09/15/1981 10:00 PM 1,861 EXMP2S.ASM
12/07/1981 10:00 PM 67,584 MASM.EXE
NOTE: Like Microsoft's unbranded MASM 1.0 (shown below), DOSBox hangs when the executable is run, although it appears
to work fine running in a command window under XP or under a MS-DOS 6.22 environment simulated by VirtualBox, at least in my experience.
In 2017, this appears to have been solved by an
entry in Christophe Lenclud's blog
where the issue was tracked down to a signedness bug originating from the
Pascal compiler's startup code.
Apparently decreasing the amount of conventional memory or patching a single byte (changing a JNG to a JNA instruction)
solves the problem.
MASM IBM 1.0 Disk |
|
|
M.EXE | 67,840 bytes (66k) | md5=82e78c6a076a3c581c5df33bc7766de8 | date=2/5/1982 12:49pm | | (file time of day may not be official) | |
|
This version likely supports the same features as the IBM branded version.
Also like the IBM version, Detect It Easy identifies this version as being built with "IBM PC Pascal".
The directory listing of the 160k distribution disk is as follows
(courtesy of pcjs.org):
Volume in drive A has no label
Directory of A:\
M EXE 67840 02-05-82 12:49p
LINK EXE 41216 02-04-82 1:47p
2 file(s) 109056 bytes
Total files listed:
2 file(s) 109056 bytes
50688 bytes free
When this version is run with no command line options, the name the MASM reports to the console is "The Microsoft MACRO Assembler".
This name appears in all of the 1.xx series versions (at least those known on this page).
Successive versions dropped the leading "The" resulting in
"Microsoft MACRO Assembler". This internal name would change slightly once more in version 4.0 to
"Microsoft (R) Macro Assembler", which would stick for all future versions.
Embedded within the oddly-named executable (M.EXE, the only version of MASM I'm aware of with this short name)
at offset 0xED83 (60803) is the identical date string we saw in the IBM branded MASM:
"8/24/81 Ver"
The file dates listed here (see below) differ by almost 6 months.
Also like the IBM version, this date string is not displayed on the command line when MASM is run with
no options.
Two separate distributions I've seen of the plain (non OEM IBM) Microsoft MASM 1.0 have identical file content
but differing timestamps. The timestamps are
identical except for being off by two hours (a time zone
difference perhaps); the time stamps between the versions of LINK.EXE were also off by
two hours. This might be viewed as an indication of an official release
date since two archives had the same day in common... or not.
Mainstream Distribution (consistent with directory listing above):
02/05/1982 12:49 PM 67,840 M.EXE
02/04/1982 01:47 PM 41,216 LINK.EXE
Alternate Distribution:
02/05/1982 10:49 AM 67,840 M.EXE
02/04/1982 11:47 AM 41,216 LINK.EXE
Although this version of MASM appears to run under XP, it hangs when run under DOSBox just as the IBM-branded
version does. See the explanation in the MASM 1.0 IBM section.
According to reports, this version was compatible with IBM PC-DOS 1.0.
SYSTEM REQUIREMENTS:
MASM.EXE | 70,784 bytes (69k) | md5=9446dcc509686be2772bf9c852a5df5b | date=2/8/1982 | | (from date embedded within executable) | |
|
I haven't found any public information about this version. It may also be an internal or unofficial release.
Similar to all prior 1.x versions, Detect It Easy identifies this version as being built with "IBM PC Pascal".
Vernon from
pcdosretro
said it definitely falls in between versions 1.0 and 1.1 as it has floating-point support but does not yet support
DOS 2+ file handles. Like MASM 1.0 it only supports /D /O /X.
The archive I found this in was bundled with the same LINK.EXE that came with version 1.10.
MASM.EXE | 77,440 bytes (76k) | md5=a9f9df1d0afd30c46f8facffffc72c64 | date=2/1/1983 1:13pm | | (file from MS-DOS source code) | |
|
This was the first version to support the 8087 opcodes.
Similar to all prior 1.x versions, Detect It Easy identifies this version as being built with "IBM PC Pascal".
File handles were also supported if running DOS 2.0 or higher (clearly Microsoft had already added file handle
support to the in-development DOS 2.0 at that point).
Little public information is available about this version, however it can be
downloaded free along with the rest of the MS-DOS 1.1 and 2.0 operating system source code as of early 2014.
The link below leads you to an article where the source code archive can be downloaded.
This archive contains MASM 1.10 (found as v20object/MASM.EXE), reportedly used to compile the MS-DOS 2.0
source code (in the v20source directory) according to computerhistory.org.
Version 2.0 of MS-DOS (the version MASM 1.10 was to compile) was the first version of
DOS to support subdirectories, hard disks, device drivers, TSRs (terminate and stay resident programs), file
redirection and 360k floppy disks (versus the previously supported 320k floppies).
Microsoft, while retaining the MS-DOS rights throughout the years, has released the source code to
the Computer History Museum (computerhistory.org) making it freely available to all for non-commercial use.
The source code can be downloaded directly from the
Microsoft MS-DOS early source code
article. After accepting the agreement, you will download: msdos.zip size=888958 (869K) md5=1687f7bcc762aac46aabf9d18fdc7622.
The changelist below was derived from Vernon of
pcdosretro.
CHANGELIST:
- Support for the Intel 8087 opcodes (coprocessor) via the /R switch
- Support for DOS 2.0+ file handles / verified with an INT 21h function tracer
MASM.EXE | 80,856 bytes (79k) | md5=2d7c908056d8e9ce4de37ca2df416aa4 | date=8/25/1982 | | (from date embedded within executable) | |
|
Little public information is available about this version.
Starting with this version, it appears "IBM PC Pascal" was no longer used to build MASM according to
Detect It Easy as no signature was recognized (it may have been ported
to assembler). It is not until version 4.0 that
the MASM EXE signatures change again as originating from Microsoft C.
The command line display for versions 1.25 and 1.27 are somewhat unique amongst the MASM series.
The command line displays spaces surrounding the comma between the name and the version, which looks odd. These
versions also center the copyright line which is not done in any other known versions.
This version was referenced by Microsoft in KB24953
and Q24962.
The original file date stamp was not preserved, but
embedded internally within the executable at offset 0x10BC7 (68551) is the string:
"8/25/82 Ver"
For this version of MASM, this was the only accurate date information available to me.
The changelist below was derived from Vernon of
pcdosretro.
CHANGELIST:
- Floating point emulation support (via the /E switch), causing the resulting .OBJ file to have an
external reference to FIDRQQ and additional fixups.
MASM.EXE | 81,280 bytes (79k) | md5=6a036d58988a65dbcae927005f5a26cf | date=11/27/1984 9:25am | | (from ACT/Apricot BETA Programmer's Toolkit) | |
|
Little public information was previously available about this version until it surfaced
in the ACT/Apricot archive on a disk labeled:
This was an Apricot/Xi RAM BIOS boot disk including the MS-DOS versions of
MASM, LINK, LIB, CREF, EXE2BIN and DEBUG utilities.
This disk did include a README.DOC which was the source of
the changelist information below. It appears this was the first version of MASM to be distributed with a
README document. Also included within the README was changelist information for LINK 2.44 and LIB 2.20.
Although the LIB version on the disk matched, the disk only included LINK 2.30.
The command line display for versions 1.25 and 1.27 are somewhat unique amongst the MASM series.
The command line displays spaces surrounding the comma between the name and the version, which looks odd. These
versions also center the copyright line which is not done in any other known versions.
The version 3.0
README.DOC hints that 1.27 may have been the predecessor to 3.0
(at least for non-IBM versions of MASM).
CHANGELIST:
- IFB & IFNB have been corrected
- Recognizes memory greater than 512K
- fsubr, fdiv & fdivr have been corrected
MASM.EXE | 76,544 bytes (75k) | md5=3bd07c55ce4161e0a644f0e8f870e8e3 | date=7/18/1984 12:01pm | | | |
|
This was the last DOS-only version Microsoft made with the IBM brand.
Future versions of MASM would be Microsoft-only with exception of IBM's 1.0 "Assembler/2" which was
a rebranded MASM 4.0 with OS/2 support 3 years later.
According to the PC Magazine article below, this version came with a manual that was one of the best instruction
set references (of the time) in the opinion of the writer. This was reportedly a solid version that was the
"top choice in the field" due to the added stability of bugfixes, a 2-volume manual that was reported as one
of the best instruction set references at the time, and the inclusion of the LIB tool. This version fixed some
problems with the SHR and SHL pesudo-op instructions and improved type-checking. The author of the article
found the in-depth inclusion of the SALUT tool in the manual (38 pages), was misplaced, especially with no
documentation beyond the command line-syntax for much-needed LIB tool. IBM SALUT, written by Scott T Jones,
stood for Structured Assembly Language Utilities; it essentially allowed the inclusion of structured
flow-controlling statements into assembly language programs that output .ASM files. According to the author, it
was a "wimpy preprocessor" written in BASIC. Microsoft must have realized this as SALUT never showed up again
in any Microsoft MASM releases, though IBM's MASM 1.0 for OS/2 (3 years later) included the last known version.
MASM 3.0 was released 4 months from this release (based on the file dates). This is also confirmed on page
137 of the article.
The changelist was derived from Vernon of
pcdosretro and the October 1985 PC magazine article below.
CHANGELIST:
- 186, 286 and 287 instruction support (.186, .286c and .287 directives)
Analysis of the binary showed 286 protected-mode instructions in the instruction tables but
can't actually be used as there is no .286p directive (wouldn't be present until version 3.0)
-
SHR and SHL pesudo-op instructions fixed
-
LIB tool added
-
IBM SALUT tool added
Article: Assembly, a Devilishly Difficult Language will Reward You
Review of IBM MASM 2.0, Microsoft's MASM 3.0 and Phoenix BIOS' Pasm86
PC Magazine
October 29, 1985
|
|
|
|
|
|
|
|
MASM.EXE | 67,968 bytes (66k) | md5=8e97eff1ceb2a0120188b8d855e125cf | date=3/2/1982 | | (from date embedded within executable) | |
|
This version was found in at least two distribution sets, so more branded sets probably exist:
- An MS-DOS 1.25 distribution OEM branded for Columbia Data Products R2.11 for their MPC 1600 and VP computers / timestamp 3/15/1982 10:00pm
- A disk labeled "SEATTLE COMPUTER Utility Software Package Version 2.04 March 1982" / timestamp 3/16/1982 2:17pm
Despite appearing to be in the MASM version 2 series, this version has a copyright year and file date placing it around the 1.0 timeframe.
Also similar to all versions prior to 1.25, Detect It Easy identifies this version as being built with "IBM PC Pascal".
WHAT OTHERS HAVE SAID:
-
According to Vernon from
pcdosretro,
this version of MASM appears to have only been called 2.04 to match the overall utility software
package(s) as it is not technically in the MASM 2.x series.
This version is clearly a rebranded MASM 1.0 as its features predate even those present in MASM 1.10.
MASM.EXE | 77,362 bytes (76k) | md5=3ba4307324e6595fe2dcf621b21f0b15 | date=11/21/1984 2:49pm | | | |
|
This version of MASM indicates in its
README.DOC
that it is "a significantly enhanced version of Microsoft Macro Assembler Package v 1.27".
This indicates that after version 1.27, Microsoft's version numbering likely skipped directly to 3.0,
and that a non-IBM MASM 2.0 never existed. I was never able to find a reference to a version 2.0 either,
officially or unofficially.
The directory listing of the 360k distribution disk is as follows
(courtesy of pcjs.org):
Volume in drive A has no label
Directory of A:\
MASM EXE 77362 11-21-84 2:49p
SYMDEB EXE 27136 12-07-84 1:39p
MAPSYM EXE 17290 11-09-84 4:22p
CREF EXE 10544 11-21-84 2:51p
LINK EXE 41114 11-14-84 2:48p
LIB EXE 24138 10-31-84 4:57p
MAKE EXE 18675 08-13-84 1:24a
README DOC 4085 12-07-84 2:30p
8 file(s) 220344 bytes
Total files listed:
8 file(s) 220344 bytes
138240 bytes free
This appeared to be the 2nd version of MASM to be distributed with a
README.DOC (1.27 was the first).
Since I have found two different distributions of MASM 3.0, both with the exact Nov 1984 date
(matching the copyright), I believe the file timestamp is the original released version.
On the command line, Microsoft abandoned the previously named "The Microsoft MACRO Assembler" for the more concise
"Microsoft MACRO Assembler" the 3.xx versions.
In the October 1985 PC Magazine Article (above), the author claimed
the Microsoft manual was a "disaster" for this version, in comparison with the IBM MASM 2.0 manual. It was
reportedly "badly printed" and only documented each instruction by exactly one line of text. In contrast, the
IBM MASM 2.0 manual was a 2 volume reference and was reported as "simply the best reference source" for
8086/8088 instructions. However, the Microsoft manual was applauded in its more in-depth discussion
of the LIB tool beyond the command line syntax. The inclusion of the SYMDEB tool was hailed as the "jewel" of
this release, noting that Microsoft's MASM was the only place you could get it and the
primary reason for his purchase. SYMDEB was good for debugging programs written with other Microsoft language
compilers such as C, FORTRAN and Pascal.
The changelist below was derived from the website:
pcdosretro.
CHANGELIST:
- Support for the Intel 80286 (286) protected-mode instruction set (via the .286p directive)
- Introduction of the MAKE, SYMDEB and MAPSYM utilities
MASM.EXE | 77,362 bytes (76k) | md5=3ba4307324e6595fe2dcf621b21f0b15 | date=11/21/1984 2:49pm | | | |
|
The actual MASM.EXE binary is identical to the 3.0 version with the 11/21/1984 date (note the identical file hashes).
Version 3.01 represents what Microsoft calls a
"Technical Update" of version 3.0 which only contains changes to MAPSYM and SYMDEB as identified in the
README.DOC.
The directory listing of the 360k distribution disk is as follows
(courtesy of pcjs.org):
Volume in drive A has no label
Directory of A:\
MASM EXE 77362 11-21-84 2:49p
LINK EXE 41114 11-14-84 2:48p
SYMDEB EXE 36538 06-07-85 4:26p
MAPSYM EXE 51904 06-21-85 10:21a
CREF EXE 10544 11-21-84 2:51p
LIB EXE 24138 10-31-84 4:57p
MAKE EXE 18675 08-13-84 1:24a
README DOC 22986 06-21-85 10:03a
8 file(s) 283261 bytes
Total files listed:
8 file(s) 283261 bytes
74752 bytes free
CHANGELIST:
- Modifications to the SYMDEB and MAPSYM utilities (described in the README.DOC)
MASM.EXE | 85,566 bytes (84k) | md5=51dc11f7a303f3d25809e5e9f36d05eb | date=10/16/1985 4:00am | | | |
|
The directory listing of the 360k distribution disk is as follows
(courtesy of pcjs.org):
Volume in drive A has no label
Directory of A:\
MASM EXE 85566 10-16-85 4:00a
LINK EXE 43988 10-16-85 4:00a
SYMDEB EXE 37021 10-16-85 4:00a
MAPSYM EXE 18026 10-16-85 4:00a
CREF EXE 15028 10-16-85 4:00a
LIB EXE 28716 10-16-85 4:00a
MAKE EXE 24300 10-16-85 4:00a
EXEPACK EXE 10848 10-16-85 4:00a
EXEMOD EXE 11034 10-16-85 4:00a
COUNT ASM 5965 10-16-85 4:00a
README DOC 7630 10-16-85 4:00a <--View Readme
11 file(s) 288122 bytes
Total files listed:
11 file(s) 288122 bytes
69632 bytes free
This version was also
included in the TOOLS directory of the Microsoft MS-DOS 3.3 OEM Adaptation Kit (OAK), described in its README as
"masm.exe from Retail Macro Assember 4.00 Product".
This version of MASM didn't include an installation program, as it was meant to be copied to a working floppy (or
hard drive) and run as-is.
This was the last version of MASM to ship with the manuals in the form of a 3-ring binder. The manuals in
version 5.0 and up were released as soft-bound booklets. This was also the last version of MASM that did not
have the capability to display its own command line options. The information listed in the New
Features section from version 4.0 User's Guide is listed below. The section opened with this blurb:
Version 4.0 of the Microsoft Macro Assembler (MASM) has been optimized to improve performance. It now
assembles code two to three times faster than any prior release. In addition, the input/output buffers and
macro text have been moved out of the symbol space, allowing assembly of larger source files.
This was the first version of MASM to be written in Microsoft C as indicated in the Microsoft Languages Newsletter
below as well as EXE dectection tools such as
Detect It Easy.
Previous versions up to 1.10 have "IBM PC Pascal" signatures. A binary analysis of this version
also shows evidence of linking with the C-Runtime libraries.
This version of MASM changed the name reported on the command line. The name changed from:
"Microsoft MACRO Assembler"
from version 3.0 to:
"Microsoft (R) Macro Assembler"
Microsoft kept the new name for all future versions.
SYSTEM REQUIREMENTS:
- A computer with one of the 8086/80186/80286 family of microprocessors
- Version 2.0 or later of the MS-DOS® or PC-DOS operating system (The manual also says "Since these
two operating systems are essentially the same, this manual uses the term MS-DOS to include both variations")
- 128K memory (The Shell command (!) of SYMDEB may require more memory)
- One double-sided disk drive (two floppy drives or one floppy with a hard disk recommended)
- A text editor capable of producing ASCII format files with no control codes
CHANGELIST:
-
New Conditional Error Directives:
These directives allow you to check parameters, boundaries, and other assembly-time values, and generate
an error if predefined conditions are not true.
-
Listing File Format Changes:
The format of the listing files produced by MASM has changed in several ways.
Several new exit codes have been added.
-
New Options for MASM:
The following command-line options have been added:
Option | | Action |
/Bnumber | - |
Sets the file buffer to any size between 1K and 63K in order to minimize disk access.
|
/C | - |
Creates a cross-reference file.
|
/L | - |
Creates an assembly listing.
|
/Dsymbol | - |
Defines a symbol (for conditional directives) from the command line or from prompts when starting
MASM.
|
/Ipath | - |
Sets path by which assembler will search for files specified with an INCLUDE directive.
|
/N | - |
Suppresses symbol table in listing.
|
/P | - |
Checks for impure code that would cause problems in 80286 protected mode.
|
/T | - |
Suppresses all messages if no errors are encountered.
|
/V | - |
Displays extra statistics to the screen after assembly.
|
/Z | - |
Displays source lines containing errors on the screen (without the option, only the error message is
shown). Previous versions of MASM always showed both source line and error message.
|
-
The command line option /O(Octal) was removed as it is no longer supported.
-
Linker Changes:
LINK has two new options: the /EXEPACK option allows you to pack executable files during linking, while
the /HELP option allows you to see a list of LINK options. In addition, LINK has been optimized to make
linking faster.
-
New Options for SYMDEB:
The following command-line options have been added:
Option | | Action |
/K | - |
Enables SCROLL LOCK or BREAK key as an interactive break-point key.
|
/N | - |
Enables non-maskable interrupt break systems for non-IBM computers.
|
/S | - |
Enables screen swapping between SYMDEB screen and a program screen.
|
/"commands" | - |
Executes the specified commands on start-up.
|
Undocumented SYMDEB Options (versions 3.0 and 4.0)
(courtesy of Vernon at pcdosretro):
Option | | Action |
/D | - |
don't assume computer is IBM compatible
|
/F | - |
ignore .SYM file
|
/R | - |
stay resident when SYMDEB exits
|
-
CREF Changes:
CREF now uses all available memory space, allowing the program to process larger cross-reference files.
-
MAKE Changes:
Two new capabilities and several options have been added to the MAKE utility. MAKE now supports macro
definitions and inference rules.
-
Introduction of Two New Utilities:
EXEPACK | - |
allows you to pack executable files.
|
EXEMOD | - |
allows you to modify the MS-DOS file header of .EXE files.
|
OFFICIAL FIXES:
- Within a couple months of the MASM 4.0 release, Microsoft published a utility to allow redirection of the
standard error device for use with MASM.EXE. This allowed the screen output in its entirety (errors and all) to be
sent to another display device such as a printer. This redirection worked pre-4.0, but no longer worked with version 4.0.
View the document (README / file_date=12/11/1985)
or download the whole MASMFIX4.ZIP package consisting of 6 files.
- According to a circulating document
(named MASM4FIX.DOC / file_date=11/20/1986),
Microsoft released manual patching instructions to address some problems MASM had with INCLUDE files. The
document also contains a "homebrew" patch, to address the inability of MASM to redirect errors sent to the
CRT.
UNOFFICIAL FIXES:
-
This version fixes the long-standing and notorious "PUSH-immediate" bug.
According to page 326
of the April 12th, 1988 issue PC Magazine in an article titled "OS/2 Programming on a Budget", Charles Petzold
recommended not to use versions of MASM prior to 4.0 due to the prevalent PUSH immediate bug,
including the IBM branded 2.0 version. The relevant text reads:
IBM's Version 2.0 and Microsoft's Version 3.0 Macro Assemblers both support the 80286 instruction
set and thus looked promising but both contain a bug that affects generation of the code for the PUSH immediate
instruction. Here's the bug: the PUSH immediate instruction has two forms. Normally, the machine code byte 68h
is followed by two bytes that indicate the word value to be pushed on the stack. However, if the immediate value
lies anywhere between FF8Oh (-128) and 7Fh (127), then the assembler can instead generate the machine code byte
6Ah followed by only one byte. The 80286 extends the sign of this byte in order to create a word before pushing
the word on the stack. In some cases, Versions 2.0 and 3.0 of the Macro Assembler generate the 68h machine code
instruction followed by only one byte of data.
Article "OS/2 Programming on a Budget" by Charles Petzold, PC Magazine April 12, 1988
|
|
|
Two months later, in another of Charles Petzold's articles (from the June 28, 1988 issue of PC Magazine,
page 292)
the sample program listing (for FSB.ASM) also recommends to avoid the same versions of MASM for their lack of proper 80286
instruction set support in addition to the "PUSH-immediate" bug described above.
(thanks to M.G. for reporting this bugfix)
WHAT OTHERS HAVE SAID:
- Eric Cohane put together a document (named MASM.DOC) dated 1/31/1986 whose purpose is to
"accumulate comments pertaining to the Microsoft Macro Assembler version 4.0 documentation that appear to be
confusing, misleading, or difficult to reconcile with experience with the assembler."
- Borland's Roger Schlafly created a bug list (named MASM400.BUG / file_date=5/11/1986)
MASM 4.0 Manual and 360K Disk Images |
|
|
|
Vintage MASM ad from Computer Language magazine Issue 11 - July 1985 (presumably version 4.0):
|
|
|
Microsoft Languages Newsletters published in PC Tech Journal Snippets About MASM 4.0: (Images Courtesy of pcjs.org)
|
|
Jan 1986 MASM Rewritten in C
|
May 1986 Good for Mainframe Software
|
May 1987 Absolute Value Tip
|
MASM401.EXE | 102,120 bytes (100k) | md5=1361f99163ec397dbaaa8e36335b8ca2 | date=7/24/1987 12:00am | | | |
|
This obscure version version appeared in the TOOLS directory of the Microsoft MS-DOS 3.3 OEM Adaptation Kit
(OAK). The OAK's README had the following description: "masm401.exe special masm used to build IO.SYS". It is
not known if this version appeared anywhere else, but this version was 16K larger than vesion 4.0!
MASM.EXE | 103,175 bytes (101k) | md5=781113d15ee597108af0cde54bd1698d | date=7/31/1987 12:00am | | | |
|
Retail Price: $150.00
This was the first version of MASM capable of displaying its own help from the command line when run with the /H option.
Additionally, it added support for the 80386 (i386) processor released by Intel in October of 1985.
This was also the first version of MASM to be distributed with nicely bound printed manuals (not spiral).
The first disk of the two disk distribution (5¼ inch floppies)
included the file PACKING.LST (shown below) illustrating the pre-install contents of the disks:
The following documentation pieces are provided with the Macro
Assembler:
Macro Assembler Programmer's Guide
Macro Assembler Reference
CodeView and Utilities Guide
Mixed-Language Programming Guide
CodeView Keyboard Templates
Old-style keyboard
New-style keyboard
The following files are provided with the Macro Assembler:
Disk 1 Root Disk 1 \MIXED Disk 2 Root
WHAT.ASM BA.ASM PAGER.ASM
RUNME.BAT CA.ASM SHOW.ASM
SETUP.BAT FA.ASM DEMO.BAT
SETUP2.BAT PA.ASM RUNME.BAT
README.DOC POWER2.ASM E_AUTO.CV
CREF.EXE BAMAIN.BAS M_AUTO.CV
ERROUT.EXE CAMAIN.C Q_AUTO.CV
EXEMOD.EXE FAMAIN.FOR U_AUTO.CV
LIB.EXE PAMAIN.PAS W_AUTO.CV
LINK.EXE MIXED.DOC CV.HLP
MAKE.EXE MIXED.INC CV.EXE
MASM.EXE EXEPACK.EXE
SETENV.EXE SHOW.EXE
SHOW.EXE WHAT.EXE
WHAT.EXE MACRO.DOC
PACKING.LST BIOS.INC
\MIXED DOS.INC
MOUSE.SYS
All 45 files on both disks had the date of midnight, July 31, 1987.
The README.DOC was a source of some of the new features listed below as some of
the late breaking features apparently did not make it into the manual. According to
Dr. Dobbs: Examining Room / Feb 1, 1988, the
price for MASM 5.0 was $150.
The Introduction page had this to say in the Version 5.0 Programmer's Guide:
Welcome to the Microsoft® Macro Assembler (MASM). This package provides all the tools you need to create
assembly-language programs.
The Macro Assembler provides a logical programming syntax suited to the segmented architecture of the
8086, 8088, 80186, 80188, 80286, and 80386 microprocessors (8086-family), and the 8087, 80287, and 80387
math coprocessors (8087-family).
The assembler produces relocatable object modules from assembly-language source files. These object modules
can be linked using LINK, the Microsoft Overlay Linker, to create executable programs for the MS-DOS®
operating system. Object modules created with MASM are compatible with many high-level-language object
modules, including those created with the Microsoft BASIC, C, FORTRAN, and Pascal compilers.
MASM has a variety of standard features that make program development easier:
• It has a full set of macro directives.
• It allows conditional assembly of portions of a source file
• It supports a wide range of operators for creating complex assembly-time expressions.
• It carries out strict syntax checking of all instruction statements, including strong typing for memory operands.
Most of the information below was derived from the "New Features" section of the Introduction
and "Appendix A: New Features" from the Version 5.0 Programmer's Guide.
SYSTEM REQUIREMENTS:
- A computer with one of the 8086-family processors (PC or PS/2 and compatibles)
- MS-DOS or IBM® PC-DOS Version 2.0 or later (The manual indicates these distributions of DOS are "essentially the same")
- 192K memory / CodeView debugger requires at least 320K
- Dr. Dobbs said: 256K minimum memory and hard disk recommended
CHANGELIST:
-
Support for the Intel 386 (80386) processor:
All instructions and addressing modes of the 80386 processor and 80387 coprocessor are now supported.
The 80386 processor is a superset of other 8086-family processors. Most new features are simply 32-bit
extensions of 16-bit features.
If you understand the features of the 16-bit 8086-family processors, then using the 32-bit extensions is
not difficult. The new 32-bit registers are used in much the same way as the 16-bit registers.
However, some features of the 80386 processor are significantly different. Areas of particular
importance include the .386 directive for initializing the 80386, the USE32 and USE16 segment types for
setting the segment word size, and indirect addressing modes.
The 8038 processor and the 80387 coprocessor also have these new instructions listed below:
Name | Mnemonic |
Bit Scan Forward | - BSF |
Bit Scan Reverse | - BSR |
Bit Test | - BT |
Bit Test and Complement | - BTC |
Bit Test and Reset | - BTR |
Bit Test and Set | - BTS |
Move with Sign Extend | - MOVSX |
Move with Zero Extend | - MOVZX |
Set Byte on Condition | - SET condition |
Double Precision Shift Left | - SHLD |
Double Precision Shift Right | - SHRD |
Move to/from Special Registers | - MOV |
Sine | - FSIN |
Cosine | - FCOS |
Sine Cosine | - FSINCOS |
IEEE Partial Remainder | - FPREM1 |
Unordered Compare Real | - FUCOM |
Unordered Compare Real and Pop | - FUCOMP |
Unordered Compare Real and Pop Twice | - FUCOMPP |
-
New segment directives allow simplified segment definitions (New Memory Model support):
A new system of defining segments is available in MASM Version 5.0.
These optional directives implement the segment conventions used in Microsoft high-level languages.
The simplified segment directives
use the Microsoft naming conventions. If you are willing to accept these conventions, segments can be
defined more easily and consistently. However, this feature is optional. You can still use the old
system if you need more direct control over segments or if you need to be consistent with existing code.
When you use simplified segment directives, ASSUME and GROUP statements that are consistent with
Microsoft conventions are generated automatically.
NOTE: The simplified segment directives cannot be used for programs written in the .COM format. You must
specifically define the single segment required for this format.
A new DOSSEG directive enables you to specify DOS segment order in the source file. This directive is
equivalent to the /DOSSEG option of the linker.
[bytepointer.com edit] What is not explicitly mentioned in the official changelist is that version 5.0
introduced the .MODEL and .CODE directives, two significant directives seen in almost all modern assembly
language source code files. The memory model and simplified segment directive information below was copied
from the 5.0 manual from various portions of sections 5.1.1. thru 5.1.7:
Memory Models:
To use simplified segment directives, you must declare a memory model for your program. The memory model
specifies the default size of data and code used in a program. Microsoft high-level languages require
that each program have a default size (or memory model). Any assembly-language routine called from a
high-level-language program should have the same memory model as the calling program.
The .MODEL directive is used to initialize the memory model. This directive should be used early in
the source code before any other segment directive. If one of the other simplified segment
directives (such as .CODE or .DATA) is given before the .MODEL directive, an error is generated.
• Syntax
.MODEL memorymodel
The memorymodel can be SMALL, MEDIUM, COMPACT, LARGE, or HUGE. Segments are defined the same for
large and huge models, but the @datasize equate is different.
The most common memory models are described below:
Model | | Description |
Tiny | |
All data and code fits in a single segment. Tiny model programs must be written in the .COM format.
Microsoft languages do not support this model. Some compilers from other companies support tiny
model either as an option or as a requirement. You cannot use simplified segment directives for
tiny-model programs.
|
Small | |
All data fits within a single 64K segment, and all code fits within a 64K segment. Therefore, all
code and data can be accessed as near. This is the most common model for stand-alone assembler
programs. C is the only Microsoft language that supports this model.
|
Medium | |
All data fits within a single 64K segment, but code may be greater than 64K. Therefore, data is
near, but code is far. Most recent versions of Microsoft languages support this model.
|
Compact | |
All code fits within a single 64K segment, but the total amount of data may be greater than 64K
(although no array can be larger than 64K). Therefore code is near, but data if far. C is the only
Microsoft language that supports this model.
|
Large | |
Both code and data may be greater than 64K (although no array can be larger than 64K). Therefore,
both code and data are far. All Microsoft languages support this model.
|
Huge | |
Both code and data may be greater than 64K. In addition, data arrays may be larger than 64K. Both
code and data are far, and pointers to elements within an array must also be far. Most recent
versions of Microsoft languages support this model. Segments are the same for large and huge models.
|
[bytepointer.com edit] It is interesting Microsoft mentions the tiny model.
Microsoft was clear that "Some compilers from other companies support tiny model" indicating
Microsoft might not have coined the term, but was aware of it. Microsoft eventually followed suit 4 years
later and in version 6.0, added support for the tiny model, using simplified segment directives.
Stand-alone assembler programs can have any model. Small model is adequate for most programs written
entirely in assembly language. Since near data or code can be accessed more quickly, the smallest memory
model that can accommodate your code and data is usually the most efficient.
Mixed-model programs use the default size for most code and data but override the default for particular
data items. Stand-alone assembler programs can be written as mixed-model programs by making specific
procedures or variables near or far. Some Microsoft high-level languages have NEAR, FAR, and HUGE
keywords that enable you to override the default size of individual data or code items.
If you are writing an assembler routine for a high-level language, the memory model should match the
memory model used by the compiler or interpreter.
If you are writing a stand-alone assembler program, you can use any model. Small model is the best
choice for most stand-alone assembler programs.
• Example 1
DOSSEG
.MODEL small
This statement defines default segments for small-model programs and creates the ASSUME and GROUP
statements used by small-model programs. The segments are automatically ordered according to the
Microsoft convention. The example statements might be used at the start of the main (or only) module
of a stand-alone assembler program.
• Example 2
.MODEL LARGE
This statement defines default segments for large-model programs and creates the ASSUME and GROUP
statements used by large-model programs. It does not automatically order segments according to the
Microsoft convention. The example statement might be used at the start of an assembly module that
would be called from a large-model C, BASIC, FORTRAN, or Pascal program.
• 80386 Only
If you use the .386 directive before the .MODEL directive, the segment definitions defines 32-bit
segments. If you want to enable the 80386 processor with 16-bit segments, you should give the .386
directive after the .MODEL directive.
Specifying DOS Segment Order:
The DOSSEG directive specifies that segments be ordered according to the DOS segment-order
convention. This is the convention used by Microsoft high-level-language compilers.
• Syntax
DOSSEG
Using the DOSSEG directive enables you to maintain a consistent logical segment order without
actually defining segments in that order in your source file. Without this directive, the final
segment order of the executable file depends on a variety of factors, such as segment order, class
name, and order of linking.
Since segment order is not crucial to the proper functioning of most stand-alone assembler programs,
you can simply use the DOSSEG directive and ignore the whole issue of segment order.
NOTE: Using the DOSSEG directive (or the /DOSSEG linker option) has two side effects. The linker
generates symbols called _end and _edata. You should not use these names in programs that contain
the DOSSEG directive. Also, the linker increases the offset of the first byte of the code segment by
16 bytes in small and compact models. This is to give proper alignment to executable files created
with Microsoft compilers.
If you want to use the DOS segment-order convention in stand-alone assembler programs, you should
use the DOSSEG argument in the main module. Modules called from the main module need not use the
DOSSEG directive. You do not need to use the DOSSEG directive for modules called from Microsoft
high-level languages, since the compiler already defines DOS segment order.
Under the DOS segment-order convention, segments have the following order:
- All segment names having the class name 'CODE'
- Any segments that do not have class name 'CODE' and are not part of the group DGROUP
- Segments that are part of DGROUP, in the following order:
a. Any segments of class BEGDATA (this class name is reserved for Microsoft use)
b. Any segments not of class BEGDATA, BSS, or STACK
c. Segments of class BSS
d. Segments of class STACK
Using the DOSSEG directive has the same effect as using the /DOSSEG linker option.
The directive works by writing to the comment record of the object file. The Intel title for this
record is COMENT. If the linker detects a certain sequence of bytes in this record, it automatically
puts segments in the DOS order.
New Predefined Equates:
-
@curseg:
This name has the segment name of the current segment. This value may be convenient for ASSUME
statements, segment overrides, or other cases in which you need to access the current segment. It
can also be used to end a segment, as show below:
@curseg ENDS ; End current segment
.286 ; Must be outside segment
.CODE ; Restart segment
-
@filename:
This value represents the base name of the current source file. For example, if the current
source file is task.asm, the value of @filename is task. This value can be used in any name you
would like to change if the file name changes. For example, it can be used as procedure name:
@filename PROC
.
.
.
@filename ENDP
-
@codesize and @datasize:
If the .MODEL directive has been used, the @codesize value is 0 for small and compact models or
1 for medium, large, and huge models. The @datasize value is 0 for small and medium models, 1
for compact and large models, and 2 for huge models. These values can be used in
conditional-assembly statements:
IF @datasize
les bx,pointer ; Load far pointer
mov ax,es:WORD PTR [bx]
ELSE
mov bx,WORD PTR pointer ; Load near pointer
mov ax,WORD PTR [bx]
ENDIF
-
@code, @data, etc.:
For each of the primary segment directives, there is a corresponding equate with the same name,
except that the equate starts with an at sign (@) but the directive starts with a period. For
example, the @code equate represents the segment name defined by the .CODE directive. Similarly,
@fardata represents the .FARDATA segment name and @fardata? represents the .FARDATA? segment
name. The @data equate represents the group name shared by all the near data segments. It can be
used to access the segments created by the .DATA, .DATA?, .CONST, and .STACK segments.
These equates can be used in ASSUME statements and at any other time a segment must be referred
to by name, for example:
ASSUME es:@fardata ; Assume ES to far data
; (.MODEL handles DS)
mov ax,@data ; Initialize near to DS
mov ds,ax
mov ax,@fardata ; Initialize far to ES
mov es,ax
NOTE: Although predefined equates are part of the simplified segment system, the @curseg and
@filename equates are also available when using full segment definitions.
Defining Simplified Segments:
The .CODE, .DATA, .DATA?, .FARDATA, .FARDATA?, .CONST, and .STACK directives indicate the start of a
segment. They also end any open segment definition used earlier in the source code.
• Syntax
.STACK [size] Stack segment
.CODE [name] Code segment
.DATA Initialized near-data segment
.DATA? Uninitialized near-data segment
.FARDATA [name] Initialized far-data segment
.FARDATA? [name] Uninitialized far-data segment
.CONST Constant-data segment
For segments that take an optional name, a default name is used if none is specified. Each new
segment directive ends the previous segment. The END directive closes the last open segment in the
source file.
The size argument of the .STACK directive is the number of bytes to be declared on the stack. If no
size is given, the segment is defined with a default size of one kilobyte. Stand-alone assembler
programs in the .EXE format should define a stack for the main (or only) module. Stacks are defined
by the compiler or interpreter for modules linked with a main module from a high-level language.
Code should be placed in a segment initialized with the .CODE directive, regardless of the memory
model. Normally, only one code segment is defined in a source module. If you put multiple code
segments in one source file, you must specify name to distinguish the segments. The name can only be
specified for models allowing multiple code segments (medium and large). Name will be ignored if
given with small or compact models.
Uninitialized data is any variable declared by using the indeterminate symbol (?) and the DUP
operator. When declaring data for modules that will be used with a Microsoft high-level language,
you should follow the convention of using .DATA or .FARDATA for initialized data and .DATA? or
.FARDATA? for uninitialized data. For stand-alone assembler programs, using the .DATA? and .FARDATA?
directives is optional. You can put uninitialized data in any data segment.
Constant data is data that must be declared in a data segment but is not subject to change at run
time. Use of this segment is optional for stand-alone assembler programs. If you are writing
assembler routines to be called from a high-level language, you can use the .CONST directive to
declare strings, real numbers, and other constant data that must be allocated as data.
Data in segments defined with the .STACK, .CONST, .DATA or .DATA? directives is placed in a group
called DGROUP. Data in segments defined with the .FARDATA or .FARDATA? directives is not placed in
any group. When initializing the DS register to access data in a group-associated segment, the value
of DGROUP should be loaded into DS.
• Example 1
DOSSEG
.MODEL SMALL
.STACK 100h
.DATA
ivariable DB 5
iarray DW 50 DUP (5)
string DB "This is a string"
uarray DW 50 DUP (?)
EXTRN xvariable:WORD
.CODE
start: mov ax,DGROUP
mov ds,ax
EXTRN xprocedure:NEAR
call xprocedure
.
.
.
END start
This code uses simplified segment directives for a small-model, stand-alone assembler program.
Notice that initialized data, uninitialized data, and a string constant are all defined in the same
data segment.
• Example 1 Equivalent (when not using simplified segment directives)
EXTRN xvariable:WORD
EXTRN xprocedure:NEAR
DGROUP GROUP _DATA,_BSS
ASSUME cs:_TEXT,ds:DGROUP,ss:DGROUP
_TEXT SEGMENT WORD PUBLIC 'CODE'
start: mov ax,DGROUP
mov ds,ax
.
.
.
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
ivariable DB 5
iarray DW 50 DUP (5)
string DB "This is a string"
uarray DW 50 DUP (?)
_DATA ENDS
STACK SEGMENT PARA STACK 'STACK'
DB 100h DUP (?)
STACK ENDS
END start
This example is equivalent to the Example 1 using simplified segment directives. Notice that the
segment order must be different in this version to achieve the segment order specified by using the
DOSSEG directive in the first example. The external variables are declared at the start of the
source code in this example. With simplified segment directives, they can be declared in the segment
in which they are used.
• Example 2
.MODEL LARGE
.FARDATA?
fuarray DW 10 DUP (?) ; Far uninitialized data
.CONST
string DB "This is a string" ; String constant
.DATA
niarray DB 100 DUP (5) ; Near initialized data
.FARDATA
EXTR xvariable:FAR
fiarray DW 100 DUP (10) ; Far initialized data
.CODE TASK
EXTR xprocedure:PROC
task PROC
.
.
.
ret
task ENDP
END
This example uses simplified segment directives to create a module that might be called from a
large-model, high-level-language program. Notice that different types of data are put in different
segments to conform to Microsoft compiler conventions.
• Example 2 Equivalent (when not using simplified segment directives)
DGROUP GROUP _DATA,CONST,STACK
ASSUME cs:TASK_TEXT,ds:FAR_DATA,ss:STACK
EXTRN xprocedure:FAR
EXTR xvariable:FAR
FAR_BSS SEGMENT PARA 'FAR_DATA'
fuarray DW 10 DUP (?) ; Far uninitialized data
FAR_BSS ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
string DB "This is a string" ; String constant
CONST ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
niarray DB 100 DUP (5) ; Near initialized data
_DATA ENDS
FAR_DATA SEGMENT WORD 'FAR_DATA'
fiarray DW 100 DUP (10)
FAR_DATA ENDS
TASK_TEXT SEGMENT WORD PUBLIC 'CODE ; < -- [bytepointer.com edit] doc bug - manual forgot closing single-quote on 'CODE'
task PROC FAR
.
.
.
ret
task ENDP
TASK_TEXT ENDS
END
This example is equivalent to the Example 2 using simplified segment directives. Notice that the
segment order is the same in both versions. The segment order shown here is written to the object
file, but it is different in the executable file. The segment order specified by the compiler (the
DOS segment order) overrides the segment order in the module object file.
Simplified Segment Defaults:
When you use the simplified segment directives, defaults are different in certain situations than
they would be if you gave full segment definitions. Defaults that change are listed below:
-
If you give full segment definitions, the default size for the PROC directive is always NEAR. If
you use the .MODEL directive, the PROC directive is associated with the specified memory model:
NEAR for small and compact models and FAR for medium, large, and huge models.
-
If you give full segment definitions, the segment address used as the base when calculating an
offset with the OFFSET operator is the data segment (the segment associated with the DS
register). With the simplified segment directives, the base address is the DGROUP segment for
segments that are associated with a group. This includes segments declared with the .DATA,
.DATA?, and .STACK directives, but not segments declared with the .CODE, .FARDATA, and FARDATA?
directives.
For example, assume the variable test1 was declared in a segment defined with the .DATA
directive and test2 was declared in a segment defined with the .FARDATA directive. The
statement
mov ax,OFFSET test1
loads the address of test1 relative to DGROUP. The statement
mov ax,OFFSET test2
loads the address of test2 relative to the segment defined by the .FARDATA directive.
Default Segment Names:
If you use the simplified segment directives by themselves, you do not need to know the names
assigned for each segment. However, it is possible to mix full segment definitions with simplified
segment definitions. Therefore, some programmers may wish to know the actual names assigned to all
segments. The table below shows the default segment names created by each directive.
Model |
|
Directive |
|
Name |
|
Align |
|
Combine |
|
Class |
|
Group |
Small | |
.CODE
.DATA
.CONST
.DATA?
.STACK
| |
_TEXT
_DATA
CONST
_BSS
STACK
| |
WORD
WORD
WORD
WORD
PARA
| |
PUBLIC
PUBLIC
PUBLIC
PUBLIC
STACK
| |
'CODE'
'DATA'
'CONST'
'BSS'
'STACK'
| |
DGROUP
DGROUP
DGROUP
DGROUP
|
|
Medium | |
.CODE
.DATA
.CONST
.DATA?
.STACK
| |
name_TEXT
_DATA
CONST
_BSS
STACK
| |
WORD
WORD
WORD
WORD
PARA
| |
PUBLIC
PUBLIC
PUBLIC
PUBLIC
STACK
| |
'CODE'
'DATA'
'CONST'
'BSS'
'STACK'
| |
DGROUP
DGROUP
DGROUP
DGROUP
|
|
Compact | |
.CODE
.FARDATA
.FARDATA?
.DATA
.CONST
.DATA?
.STACK
| |
_TEXT
FAR_DATA
FAR_BSS
_DATA
CONST
_BSS
STACK
| |
WORD
PARA
PARA
WORD
WORD
WORD
PARA
| |
PUBLIC
private
private
PUBLIC
PUBLIC
PUBLIC
STACK
| |
'CODE'
'FAR_DATA'
'FAR_BSS'
'DATA'
'CONST'
'BSS'
'STACK'
| |
DGROUP
DGROUP
DGROUP
DGROUP
|
|
Large or huge | |
.CODE
.FARDATA
.FARDATA?
.DATA
.CONST
.DATA?
.STACK
| |
name_TEXT
FAR_DATA
FAR_BSS
_DATA
CONST
_BSS
STACK
| |
WORD
PARA
PARA
WORD
WORD
WORD
PARA
| |
PUBLIC
private
private
PUBLIC
PUBLIC
PUBLIC
STACK
| |
'CODE'
'FAR_DATA'
'FAR_BSS'
'DATA'
'CONST'
'BSS'
'STACK'
| |
DGROUP
DGROUP
DGROUP
DGROUP
|
The name used as part of the far-code segment names is the file name of the module. The default name
associated with the .CODE directive can be overridden in medium and large models. The default names
for the .FARDATA and .FARDATA? directives can always be overridden.
The segment and group table at the end of listings always shows the actual segment names. However,
the group and assume statements generated by the .MODEL directive are not shown in listing files.
For a program that uses all possible segments, group statements equivalent to the following would be
generated:
DGROUP GROUP _DATA,CONST,_BSS,STACK
For small and compact models, the following would be generated:
ASSUME cs:_TEXT,ds:DGROUP,ss:DGROUP
For medium, large, and huge models the following statement is given:
ASSUME cs:name_TEXT,ds:DGROUP,ss:DGROUP
80386 Only:
If the .386 directive is used, the default align type for all segments is DWORD.
Example EXE and COM source code:
[bytepointer.com edit] The version 5.0 manual has an example a source file to build an .EXE using
the simplified segment directives and another example source file to build an equivalent .COM file
(simplified segment directives not supported) on pages 14-16. Those examples are shown below:
The source to build an .EXE file:
TITLE hello
DOSSEG ; Use Microsoft segment conventions
.MODEL SMALL ; conventions and small model
.STACK 100h ; Allocate 256-byte stack
.DATA
message DB "Hello, world.",13,10 ; Message to be written
lmessage EQU $ - message ; Length of message
.CODE
start: mov ax,@DATA ; Load segment location
mov ds,ax ; into DS register
mov bx,1 ; Load 1 - file handle for
; standard output
mov cx,lmessage ; Load length of message
mov dx,OFFSET message ; Load address of message
mov ah,40h ; Load number for DOS Write function
int 21h ; Call DOS
mov ax,4C00h ; Load DOS Exit function (4Ch)
; in AH and 0 errorlevel in AL
int 21h ; Call DOS
END start
The following example shows source code that can be used to create the same program as above, but
in .COM format:
TITLE hello
_TEXT SEGMENT ; Define code segment
ASSUME cs:_TEXT,ds:_TEXT,ss:_TEXT
ORG 100h ; Set location counter to 256
start: jmp begin ; Jump over data
message DB "Hello, world.",13,10 ; Message to be written
lmessage EQU $ - message ; Length of message
begin: mov bx,1 ; Load 1 - file handle for
; standard output
mov cx,lmessage ; Load length of message
mov dx,OFFSET message ; Load address of message
mov ah,40h ; Load number for DOS Write function
int 21h ; Call DOS
mov ax,4C00h ; Load DOS Exit function (4Ch)
; in AH and 0 errorlevel in AL
int 21h ; Call DOS
_TEXT ENDS
END start
[bytepointer.com edit] Note, to build the COM file sample, you had to perform these steps in MASM 5.0:
- assemble with MASM to obtain the OBJ file
masm example.asm;
- LINK the OBJ file to produce the unusable/dummy EXE file (ignore the linker warning "L4021: no
stack segment")
link example.obj;
- run EXE2BIN from your DOS distribution passing the dummy EXE filename and specifying the output
COM filename
exe2bin example.exe example.com
Jump to the improved COM file support and updated example for version 6.0.
The COM file support in version 6.0 removed the need to run EXE2BIN as the linker will produce the
COM file directly. MASM also added support for the
tiny model, allowing for the use of simplified segment directives; this greatly simplified the COM
source-code mess above. It is implied that debugging info for COM files was supported in
version 6.0, although CodeView didn't support COM debugging until 1994 when the following patch was
released:
cv41patch.exe
Performance Improvements:
The performance of MASM has been enhanced in two ways: faster assembly and larger symbol space.
Version 5.0 of the assembler is significantly faster for most source files. The improvement varies
depending on the relative amounts of code and data in the source file, and on the complexity of
expressions used. Symbol space is now limited only by the amount of system memory available to your
machine.
Enhanced Error Handling:
-
Messages have been reworded/clarified, enhanced, or reorganized.
-
Messages are divided into three levels: severe errors, serious warnings, and advisory warnings.
The level of warning can be changed with the /W option. Type-checking errors are now serious
warnings rather than severe errors.
-
During assembly, messages are output to the standard output device (by default, the screen).
They can be redirected to a file or device. In Version 4.0 they were sent to the standard error
device.
New Options:
The following command-line options have been added:
Option | | Description |
/W[0|1|2] | - |
Sets the warning level to determine what type of messages will be displayed. The three kinds are
severe errors, serious warnings, and advisory warnings.
|
/ZI and /ZD | - |
Sends debugging information for symbolic debuggers to the object file. The /ZD option outputs
line-number information, whereas the /ZI option outputs both line-number and type information.
|
/H | - |
Displays the MASM command line and options.
|
/Dsym[=val] | - |
Allows definition of a symbol from the command line. This is an enhancement of a current option.
|
/LA | - |
The /LA option has been added to specify a complete listing of all symbols, macros, and false
conditionals. It is equivalent to using the .LIST, .LFCOND, .LALL, and .CREF directives throughout
the source file. The option overrides any conflicting directives in the source file.
NOTE: This was formally documented in version 5.1 as a new feature
over 5.0, but that was a documentation bug. This feature was present in version 5.0, but only
documented in the README.DOC.
|
In addition, the new directives .ALPHA and .SEQ have been added; these directives have the same effect
as the /A and /S options.
Environment Variables:
MASM now supports two environment variables: MASM for specifying default options, and INCLUDE for
specifying the search paths for include files.
String Equates:
String equates have been enhanced for easier use. By enclosing the argument to the EQU directive in
angle brackets, you can ensure that the argument is evaluated as a string equate rather than as an
expression.
The expression operator (%) can now be used with macro arguments that are text macros as well as
arguments that are expressions.
RETF and RETN Instructions:
The RETF (Return Far) and RETN (Return Near) instructions are now available. These instructions enable
you to define procedures without the PROC and ENDP directives.
Communal Variables:
MASM now allows you to declare communal variables. These uninitialized global data items can be used in
include files. They are compatible with variables declared in C include files.
Including Library Files:
The INCLUDELIB directive enables you to specify in the assembly source file any libraries that you want
to be linked with your program modules.
Flexible Structure Definitions:
Structure definitions can now include conditional-assembly statements, thus enabling more flexible
structures.
New Macro Files:
Macro files have been added to the Macro Assembler package.
The following files are provided:
MIXED.INC |
- For defining assembler procedures that can be called from high-level languages
|
MIXED.DOC |
- Documentation for the macros in MIXED.INC.
|
DOS.INC |
- For calling common DOS interrupts
|
BIOS.INC |
- For calling common BIOS interrupts used on IBM and IBM-compatible computers
|
MACRO.DOC |
- Description, syntax, and reference for using the macros in DOS.INC and BIOS.INC.
|
Link Enhancements:
LINK has several new features. These enhancements are summarized below:
Real-number format changed to IEEE floats:
The default format for initializing real-number variables has been
changed from Microsoft Binary to the more common IEEE (Institute of
Electrical and Electronic Engineers, Inc.) format.
Introduction of the CodeView debugger:
The new CodeView® window-oriented debugger allows source-level
debugging on assembly language files and has many other powerful
features.
In Version 5.0 of the Macro Assembler package, the CodeView debugger replaces SYMDEB.
[bytepointer.com edit] CodeView also replaced the MAPSYM utility.
The CodeView
debugger is a source-level symbolic debugger capable of working with programs developed with MASM or
with Microsoft high-level-language compilers.
The CodeView debugger features a window-oriented environment with multiple windows displaying different
types of information. Commands can be executed with a mouse, function keys, or command lines. Variables
can be watched in a separate window as the program executes.
MASM and LINK have been enhanced to support the features of the CodeView debugger.
-
The /R option has been added to enable the CodeView debugger to use the debug registers (DR0,
DR1, DR2, and DR3) of the 80386 processor. The option is ignored if you do not have an 80386
processor.
The display does not change to indicate that the debug registers are in use, but debugger
operations with tracepoint or trace memory statements (but not with watchpoint statements) will
be much faster. Any of the following conditions will prevent the debugger from using debug
registers:
1) /E is used.
2) More than four tracepoints are set.
3) A tracepoint watches more than four bytes of memory.
4) A watchpoint is set.
CREF.EXE has new Modifier Symbol:
Cross-reference listing files created with CREF now have an additional symbol. A line number followed
by + indicates that a symbol is modified at the given line. For example:
TST . . . . . . . . . . . . . . 134# 237 544+
The symbol TST is defined at line 134, used at line 237, and
modified at line 544.
SETENV:
Since MASM and LINK now support more environment variables, users may wish to define environment
strings that exceed the default size of the DOS environment. The SETENV program in the CodeView and
Utilities manual is provided as a means of modifying the environment size for DOS Versions 2.0 to 3.1.
Compatibility with Assemblers and Compilers:
If you are upgrading from a previous version of the Microsoft or IBM Macro Assembler, you may need to
make some adjustments before assembling source code developed with previous versions. The potential
compatibility problems are listed below:
-
All previous versions of the Macro Assembler assembled initialized real-number variables in the
Microsoft Binary format by default. Version 5.0 assembles initialized real-number variables in
the IEEE format. If you have source modules that depend on the default format being Microsoft
Binary, you must modify them by placing the .MSFLOAT directive at the start of the module before
the first variable is initialized.
In previous versions of the Macro Assembler, the default conditions were 8086 instructions
enabled, coprocessor instructions disabled, and real numbers assembled in Microsoft Binary
format. The /R option, the .8087 directive, or the .287 directive was required to enable
coprocessor instructions and IEEE format. In Version 5.0, the default conditions are 8086 and
8087 instructions enabled and real numbers assembled in IEEE format. Although the /R option is
no longer used, it is recognized and ignored so that existing make and batch files work without
modification.
-
Some previous versions of the IBM Macro Assembler wrote segments to object files in alphabetical
order. MASM Version 5.0 writes segments to object files in the order encountered in the source
file. You can use the /A option or the .ALPHA directive to order segments alphabetically if this
segment order is required for your existing source code.
-
Some early versions of the Macro Assembler did not have strict type checking. Later versions had
strict type checking that produced errors on source code that would have run under the earlier
versions. MASM Version 5.0 solves this incompatibility by making type errors into warning
messages. You can set the warning level so that the type warnings will not be displayed, or you
can modify the code so that the type is given specifically.
The programs in the Microsoft Macro Assembler package are compatible with Microsoft (and most IBM)
high-level languages. An exception occurs when the current version of LINK is used with IBM COBOL 1.0,
IBM FORTRAN 2.0, or IBM Pascal 2.0. If source code developed with these compilers has overlays, you must
use the linker provided with the compiler. Do not use the new version of LINK provided with the
assembler.
WHAT OTHERS HAVE SAID:
- "There's no excuse for using an Assembler earlier than MASM 5.0--you might as well use DEBUG. Version
5.00 was much faster than 4.00, and miles ahead in bug fixes. The most significant improvement was
simplified segment declarations like .MODEL and .CODE. But 5.00 didn't hang around long; it was quickly
replaced..."
REFERENCE: r_harvey
-
"The real purpose of this letter is to complain that MASM 5.0 no longer supports .COM files and nobody says
anything about it. CodeView does not offer symbolic debugging of .COM files and MASM 5.0's symbol file is not
compatible with Symdeb or other symbolic disassemblers. So even if you're satisfied with the creepy-crawly rate
at which MASM 5.0 assembles and links, you have to give up .COM files or symbolic debugging."
...
EDITOR RESPONSE SNIP:
"In comparison with earlier releases, MASM 5.0 is "screamingly" faster. There are even faster assemblers, and
I'll take George's word that A86 is one of them. It's true that MASM 5.0 doesn't produce .COM files directly;
you have to run the end product through EXE2BIN if you want a .COM. It's also true that I didn't mention that,
and I apologize on behalf of all us reviewers who haven't said anything about it."
REFERENCE: Dr. Dobbs: MASM Complaints / May 1, 1988
-
"To that end, MASM 5.0 furnishes a macro library for mixed-language programming. This file, MIXED.INC,
includes macros for passing and receiving anguments, allocating local variables on the stack, segment
fixups, exit processing, and other high-level interfacing needs. The macro library is propped up by and
excellent 1440-page guide covering a range of mixed-language programming issues."
...
"The overall quality of the manuals is much better than any previous Microsoft documentation. In addition to
the mixed-language guide, there are two soft-bound books, a 467-page Programmer's Guide and a 401-page
volume covering CodeView and other utilities. Rounding out the documentation is a 148-page wire-bound
reference divided into five tabbed sections. Intended to be kept at the programmer's elbow, this reference
summarizes every instruction, pseudo-op, and command-line switch. There are several brochures and a
function-key template for operating CodeView."
...
"If you haven't worked with CodeView before, you're missing out on the finest thing Microsoft has done to
date. This is how God intended a symbolic debugger to be. It's a wonderfully visual environment that lets
you watch your code execute while keeping an eye on registers and selected memory locations. Codeview runs
in a secondary video page, thus not interfering with programs that do graphics or fancy text screens, and
you can easily toggle back and forth between the CodeView display and your program's output. Accommodating
to all and sundry, CodeView lets you control it via pulldown menus, function keys, typed commands, or a
mouse: your choice."
REFERENCE: Dr. Dobbs: Examining Room / Feb 1, 1988
- In September 1987, some users of DANNYSOFT BBS reported certain problems encountered in version 5.0 in a
compilation document (named MASMV5P1.TXT).
MASM 5.0 Mixed-Language Guide and 5¼ inch disks |
|
|
MASM 5.0 Features Microsoft Languages Newsletters September 1987: (Images Courtesy of pcjs.org)
|
|
|
MASM.EXE | 114,522 bytes (112k) | md5=4c7a1562e1151c5168238cbbc8d86858 | date=9/3/1987 4:00pm | | | |
|
This is a unique version of MASM displaying the name "IBM Macro Assembler/2" and "Version 1.00".
It is important to note that this is actually a rebranded variant of MASM 4.0 with OS/2 support, although DOS
remains supported.
The executable size in this version was nearly 30k larger than in MASM 4.0 because this was
a "bound" executable, allowing it to be run in both DOS and OS/2. Likewise, the LINK, LIB, CREF, MAKE and
EXEMOD utilities were also bound executables. However, CodeView was distributed in pure DOS and OS/2
executable forms as CV and CVP respectively.
Archive.org has a copy of this version's
Reference Manual
available for viewing or download.
The mainstream Microsoft MASM wouldn't have OS/2 support until the following year in version 5.1.
IBM did not appear to release another "Assembler/2" or another rebranded MASM.
SYSTEM REQUIREMENTS:
- IBM Disk Operating System Version 3.30 or
IBM Operating System/2
MASM.EXE | 110,703 bytes (108k) | md5=6828fe2509ebad3ca10d2f51c71a2d94 | date=2/1/1988 1:00pm | | (dos version) | | [Command Line] |
MASM.EXE | 124,712 bytes (122k) | md5=c1a93ab5293080614af1fe0302e5420a | date=1/31/1988 11:00pm | | (dual mode version) | | [Command Line] |
|
@Version reports: 510
Retail Price: $150.00
I have seen multiple file dates for both the DOS and "dual mode" versions of the MASM.EXE files.
Note that differences of a couple hours may be from an inadvertent time zone adjustment
rather than an official time stamp.
- DOS version: 1/31/1988 9:00pm, 2/1/1988 1:00pm
- Dual mode version: 1/31/1988 9:00pm, 1/31/1988 11:00pm, 3/10/1988 1:10pm (on EXTRA disk, #6)
Despite the the minor number increment over 5.0, this release of MASM had enough changes to warrant
a major release.
The was the first Microsoft branded version of
MASM to support OS/2 (see the IBM rebranded MASM "Assembler/2").
This version of MASM was a 5 disk distribution of 5¼ inch floppies. It is not
known if this version was released on 3 ½ inch floppies.
The
PACKING.LST file distributed on disk #1 illustrates the
pre-install contents of the disks. Additionally, the other documentation files provided include:
README.DOC,
MACRO.DOC,
and MIXED.DOC.
Although this version shipped with the 5.0 User's Guide, it included an
additional lengthy booklet divided into three sections labeled: "5.1 Update"; "Microsoft® CodeView® and Utilities
Update"; and "Microsoft Editor".
The majority of the information below was derived from the official 5.1 Update manual.
Note: Not all the OS/2 changes were listed.
SYSTEM REQUIREMENTS (from "Technical Highlights" card below):
- 320K available user memory
- MS OS/2 1.0 or MS-DOS 2.1 or higher
- Two double-sided disk drives
MINIMUM SYSTEM REQUIREMENTS FOR ASSEMBLED PROGRAMS:
-
Regular DOS programs:
[bytepointer.com edit] I couldn't find anything explicitly said, but the minimum requirement for running
this version of MASM was DOS 2.1 and up; assembled programs in version 6.0 had a minimum requirement of
DOS 2.1 and up, so a DOS 2.1 or higher requirement seems logical.
-
Bound Hybrid (dual-mode) OS/2 and DOS Programs:
OS/2 and DOS version 3.0 or higher is required for dual-mode programs that run under either DOS or OS/2,
but the OS/2 API calls must be restricted to the "Family API".
A dual-mode executable can however be run in DOS 2.x environments, but only if the name of an executable file
produced by BIND is not changed.
CHANGELIST:
-
New OS/2 Support:
Version 5.1 runs under both OS/2 and DOS operating systems, enabling you to develop powerful
applications for OS/2. Version 5.1 includes the necessary supporting libraries including bound and
real-mode versions.
[bytepointer.com edit] This includes the introduction of the BIND utility, used for creating "bound"
programs. A bound program was a single executable that was capable of running under both DOS and OS/2.
-
Text-macro and directive extensions:
New directives, text-macro directives, and predefined text macros let you write more sophisticated
macros for powerful and portable code.
Extensions to text macros let you write more flexible and powerful macros for your programs. Version 5.1
includes new built-in text macros as well as text macro directives that let you directly manipulate
string equates. An extension to the expression operator (%) allows you to evaluate text macros anywhere
in your source.
Version 5.1 of the Macro Assembler includes four text-macro string directives that let you manipulate
literal strings or text-macro values.
-
SUBSTR: Returns a substring of its text macro or literal string argument. The SUBSTR
directive requires a text-macro label.
-
CATSTR: Concatenates a variable number of strings (text macros or literal strings) to
form a single string. The CATSTR directive requires a text-macro label.
-
SIZESTR: Returns the length, in characters, of its argument string. The SIZESTR directive
requires a numeric label.
-
INSTR: Returns an index indicating the starting position of a substring within another
string. The INSTR directive requires a numeric label.
Version 5.1 of the Macro Assembler includes three new predefined text-macros:
-
@WordSize: The @WordSize text macro returns the word size of the segment word size in
bytes. It returns 4 when the word size is 32 bits and 2 when the word size is 16 bits. By
default, the segment word size is 16 bits with the 80286 and other 16-bit processors, and 32
bits with the 80386.
-
@Cpu: The @Cpu text macro returns a 16-bit value containing information about the
selected processor. You select a processor by using one of the processor directives such as the
.286 directive. You can use the @Cpu text macro to control assembly of processor-specific code.
Individual bits in the value returned by @Cpu indicate information about the selected processor.
-
@Version: The @Version text macro returns a string containing the version of MASM in use.
With the @Version macro, you can write macros for future versions of MASM that take appropriate
actions when used with inappropriate versions of MASM. Currently, the @Version macro returns 510
as a string of three characters.
-
High-level-language support:
Version 5.1 contains several features that simplify the writing of assembly routines to be called from
high-level languages. The high-level-language support features incorporate and extend the features of
the mixed-language programming macros distributed with Version 5.0.
Features of the MIXED.INC macro file shipped with Version 5.0 are now built into the macro assembler,
along with additional supporting directives and extensions:
-
New Language parameter to .MODEL:
Along with simplifying the process if writing procedures to be called from other
languages, the high-level-language calling features also make it easier to use a
procedure with more than one language. For example, to change function(s) so they can
be called from Pascal, rather than C, you would change the .MODEL directive.
Additionally:
-
Possible values:
You can use C, PASCAL, FORTRAN, or BASIC as the language argument.
-
Makes procedures public:
If you use the language argument, MASM automatically makes all procedure names public.
In Version 5.0 of MASM, a procedure required a PUBLIC directive to make the name of
the procedure available outside the module. The PUBLIC directive is no longer required when
used with the new language parameter.
-
Sets naming conventions:
If you use C for the language parameter, all public and external names are prefixed with
an underscore (_) in the .OBJ file. Specifying any other language has no effect on the
names.
NOTE: The only change MASM makes to a procedure name is to add an underscore for C. MASM does
not truncate names in order to match the conventions of specific languages such as
FORTRAN or Pascal.
-
Sets parameter order:
The language parameter also affects how arguments passed on the stack are interpreted.
If you specify FORTRAN, PASCAL, or BASIC, then MASM assumes the arguments have been
pushed onto the stack from left to right - the last argument is nearest to the top of
the stack. Specifying C assumes arguments have been pushed on the stack in the opposite
order.
-
Sets return conventions:
Pascal, FORTRAN, and BASIC programs require the called procedure to remove arguments
from the stack. If you specify PASCAL, FORTRAN or BASIC as the language argument, MASM
replaces you return instruction (ret) with a return that removes the correct number of
bytes from the stack. In C, the calling program removes arguments from the stack, and
MASM leaves the return instruction unchanged.
NOTE: To write procedures for use with more than one language, you can use text macros
for the memory model and language arguments, and define the values from the command
line. For example, the following .MODEL directive uses text macros for the memory and
language arguments:
% .MODEL memmodel,lang ; Use % to evaluate memmodel, lang
The values of the two text macros can be defined from the command line using the /D
switch:
MASM /Dmemmodel=MEDIUM /Dlang=BASIC
-
Changes to EXTRN and PUBLIC syntax:
EXTRN and PUBLIC now allow the langtype parameter:
EXTRN [langtype] varname:type
PUBLIC [langtype] varname
-
Extensions to the PROC directive:
In Version 5.1, the PROC directive has this syntax:
name PROC [NEAR|FAR] [langtype] [USES [reglist],] [argument[,argument]...]
where
argument[:[[NEAR|FAR]PTR]type]...
-
Automatically save specified registers on the stack with USES:
reglist specifies a list of registers that the procedure uses and that should be
saved on entry. Registers in the list must be separated by blanks or tabs.
-
Automatically generate text macros for arguments passed on the stack:
In Version 5.0, the type and number of arguments were handled as displacements from the
base pointer, BP. Version 5.1 extends the PROC directive to specify the type and number
of arguments passed to the procedure on the stack and generates text macros for the
arguments. Additionally, MASM now generates the code for setting up the stack and
restoring it based on the information in the high-level-language-directives.
The argument is the name of the argument. The type is the type of the
argument and may be WORD, DWORD, FWORD, QWORD, TBYTE, or the name of a structure defined
by a STRUC structure declaration. If you omit type, the default is the WORD type
(the DWORD type when a 386 directive is used). MASM creates a text macro for each
argument. You can use these text macros to access the arguments in the procedure. The
FAR, NEAR, PTR, and type arguments are all optional. If you specify that the
variable is a pointer, MASM sets up a text macro to access the variable on the stack,
but also generates CodeView information so that the variable is treated as a pointer
during debugging.
The following is a routine using the old high-level-language techniques present in Version 5.0
(a procedure to be called from a C program as a function adding two integers and returning the
result AX, used by C for returning integer function values):
; Assemble with /MX or ML to preserve case of procedure name
PUBLIC _myadd
.MODEL MEDIUM
.CODE
_myadd PROC FAR
arg1 EQU <WORD PTR [bp+6]>
arg2 EQU <WORD PTR [bp+8]>
push bp ; Set up stack frame
mov bp,sp
mov ax,arg1 ; Load first argument
add ax,arg2 ; Add second argument
pop bp
ret
_myadd ENDP
END
Here is the same procedure written using the new high-level-lanaguage features:
.MODEL MEDIUM,C
.CODE
myadd PROC arg1:WORD, arg2:WORD
mov ax,arg1 ; Load first argument
add ax,arg2 ; Add second argument
ret
myadd ENDP
END
-
The new LOCAL directive:
[bytepointer.com edit] Its not just for Macro's anymore!
With the LOCAL directive, you can allocate local variables from the stack and MASM will generate
text equates for the variables. Usually this is done by decrementing the stack pointer the
required number of bytes after setting up the stack frame. For example, the following sequence
allocates two, two-byte variables from the stack and sets up text macros to access them:
locvar1 EQU <WORD PTR [bp-2]>
locvar2 EQU <WORD PTR [bp-4]>
.
.
.
push bp
mov bp,sp
sub sp,4
.
.
.
mov localvar1,ax
With the LOCAL directive you can do the same thing in a single line:
LOCAL locvar1:WORD, locvar2:WORD
.
.
.
mov localvar1,ax
The LOCAL directive has the following syntax:
LOCAL vardef [,vardef]...
Each vardef has the form:
variable[[count]][:[[NEAR | FAR]PTR]type]...
The LOCAL directive arguments are as follows:
Argument | | Description |
variable | - |
The name given to the local variable. MASM automatically defines a text macro you
may use to access the variable.
|
count | - |
The number of elements of this name and type to allocate on the stack. Using
count allows you to allocate a simple array on the stack. The brackets around
count are required.
|
type | - |
The type of variable to allocate. The type argument may be one of the
following: WORD, DWORD, FWORD, QWORD, TBYTE, or the name of a structure defined by a
STRUC structure declaration.
|
MASM sets aside space on the stack, following the same rules as for procedure arguments.
MASM does not initialize local variables. Your program must include code to perform any
necessary initializations.
-
Variable Scope:
Labels can be made local to a procedure, allowing better isolation of the procedures.
When you use the extended form of the .MODEL directive, MASM makes all identifiers inside a
procedure local to the procedure. Labels ending with a colon (:), procedure arguments, and local
variables declared in a LOCAL directive are undefined outside of the procedure. Variables
defined outside of any procedure are available inside a procedure.
Because labels are local when you use the language option on the .MODEL directive, you may use
the same labels in different procedures. You can make a label in a procedure global (make it
available outside the procedure) by ending it with two colons.
-
Local Labels for Jumps:
Version 5.1 of the Macro Assembler allows automatic generation of local labels
for jump instructions. Automatic local labels free you from having to write labels for small code
sections. To define a local label, use two at signs (@@) followed by a colon (:). To jump to the nearest
preceding local label, use @B (back) in the jump instruction's operand field; to jump to the nearest
following local label, use @F (forward) in the operand field.
-
Conditional Assembly:
The ELSEIF directive simplifies the writing of complex conditional assembly sections in
your macros and programs. MASM includes an ELSEIF directive corresponding to each of the IF directives:
ELSEIF, ELSEIF1, ELSEIF2, ELSEIFB, ELSEIFDEF, ELSEIFDIF, ELSEIFDIFI, ELSEIFE, ELSEIFIDN,
ELSEIFIDNI, ELSEIFNB, ELSEIFNDEF
-
Data Declarations:
A new type of data declaration makes it possible to generate Microsoft CodeView® information for
pointer variables. Version 5.1 of the Macro Assembler extends data definitions to include explicit
allocation of a pointer. Pointer-data definitions may now have the following form:
symbol[DW | DD | DF]type PTR initialvalue
For example, in the following fragment, ndptr is declared as a near pointer to a date structure and is
initialized to zero:
date STRUC
month DB ?
day DB ?
year DB ?
date ENDS
ndptr DW date PTR 0
Similarly, the following lines declare a string and two pointers to the string. The declaration also
initializes the pointers to the address of the string:
string DB "from swerve of shore to bend of bay"
pstring DW BYTE PTR string ; Declares a near pointer.
fpstring DD BYTE PTR string ; Declares a far pointer.
Using an explicit pointer declaration generates CodeView information, allowing the variable to be viewed
as a pointer during debugging.
NOTE: This use of PTR is in addition to the use of PTR to specify the type of a variable or operator.
MASM 5.1 determines the meaning of PTR by context.
-
Changes to the .CODE directive:
A change in the register assumptions used in the .CODE directive makes it easier to create multiple code
segments. In Version 5.1, the .CODE directive always assumes CS is the current segment. This change
makes it easier to use multiple code segments in a single module. Version 5.0 assumed CS once at the
beginning of the program, making it necessary to use an ASSUME for a second segment.
-
Mixed-Mode Programming with .386:
When assembling code for .386 mode, the assembler now supports direct- addressing modes between segments
with different USE sizes. (Segments can have the USE16 or USE32 attribute; these attributes refer to
the default size of offsets.) Direct-addressing references to labels in other segments are correctly
resolved. In the following example, the assembler correctly uses a 32-bit offset to access the data at
label a32:
.386
SEG32 SEGMENT USE32
a32 DD ?
SEG32 ENDS
SEG16 SEGMENT USE16
assume ds:seg32
mov eax,a32
SEG16 ENDS
You can also execute a CALL or a JMP to a label in a segment with a different USE size. However, the
label must be declared FAR, and the CALL or JMP must not be a forward reference. The following example
shows the correct method for executing such a CALL or JMP:
.386
COD16 SEGMENT USE16 'CODE'
proc16 PROC FAR
ret
proc16 ENDP
lab16 LABEL FAR
COD16 ENDS
COD32 SEGMENT USE32 'CODE'
call proc16
jmp lab16
COD32 ENDS
-
.TYPE Operator:
Extensions to the .TYPE operator provide additional information about an operand. The .TYPE operator
now returns the following bit settings as shown in the .TYPE Operator and Variable Attributes table:
Bit Position | | If Bit=0 | | If Bit=1 |
0 | | Not program related | | Program related |
1 | | Not data related | | Data related |
2 | | Not a constant value | | Constant value |
3 | | Addressing mode is not direct | | Addressing mode is direct |
4 | | Not a register | | Expression is a register |
5 | | Not defined | | Defined |
7 | | Local or public scope | | External scope |
It bits 2 and 3 are both zero, the expression involves a register-indirect expression. Bit 6 is
reserved. The use of bits 2,3, and 4 is new with this version of the Macro Assembler.
-
COMM Extension:
The COMM directive now accepts structure names for the size argument. This enhancement lets you
declare communal variables of any size, rather than being limited to 1-,2-,4-,6-,8-, or 10-byte items.
-
Line Continuation:
Version 5.1 lets you use the line-continuation character (\) to continue program lines. Using the
line-continuation character, you may have program lines up to 512 characters. Physical lines are still
limited to 128 characters. The backslash must be the last character in the line.
-
Performance:
Version 5.1 is significantly faster than Version 5.0 because it uses dynamically allocated memory to
perform file caching. File caching stores significant parts of the source and include files to be stored
in memory.
In addition, Version 5.1 allows significantly more structure definitions because it now uses far memory
to store these definitions.
-
Command Line Options:
Version 5.1 of the Macro Assembler includes a new command line-option that shows all code generated by MASM.
The /LA option displays the results of the simplified segment directives and the code generated by the
high-level-language support features.
[bytepointer.com edit] Doc bug. /LA was new in 5.0 too, but it didn't make it into the manual, just the README.
The following command line option was removed that was present in version 5.0:
/B<number> |
- |
Set I/O buffer size, 1-63 (in 1K blocks)
The /B option is now ignored, because its effect is irrelevant,
given the new file buffering mechanism. However, the option is
still accepted for the purposes of compatibility.
|
-
Command-Line Changes to CodeView:
If you have an IBM Personal System/2, then you can use the /50 command-line option to start the
CodeView debugger in 50-line mode. Note that you must be in 25-line mode to effectively use
either the /43 or /50 command-line option.
-
CodeView and Microsoft Pascal:
In this release, Microsoft Pascal programs cannot be debugged with the CodeView debugger.
-
LIB Utility Changes:
There is a new option for LIB: /NOIGNORECASE (abbreviated as /N). This option tells LIB to not ignore
case when comparing symbols. names. By default, LIB ignores case. Multiple symbols that are the same
except for case can be put in the same library. An example of this is: "_Open" and "_open". Normally
you could not add both these symbols to the same library.
Note that if a library is built with /NOI, the library is internally "marked" to indicate /NOI. All
libraries built with earlier versions of LIB are not marked.
If you combine multiple libraries, and any one of them is marked /NOI, then /NOI is assumed for the
output library.
In addition, LIB also supports the option /IGNORECASE (/I), which is completely analogous to
/NOIGNORECASE. /I is the default. The only reason to use it would be if you have an existing library
marked /NOI that you wanted to combine with other libraries which were not marked, and have the output
library be not marked. If you don't use /IGNORECASE, the output is marked /NOI (see above).
WHAT OTHERS HAVE SAID:
-
"The idea is simple: you define a local label with two at signs (@@) followed by a colon. To reference the
nearest preceding local label, use @B (back); to reference the next local label, use @F (forward). When
writing assembly language routines for use in HLL programs, a much more structured feature is enabled. The
manual describes it as a local variable scope when you use the extended form of the .MODEL directive. Labels
ending with a single colon (and procedure arguments passed on the stack and local stack variables) are
considered local to the procedure where they are defined. To make a label available from another procedure,
it must be defined with two colons."
REFERENCE: Dr. Dobbs: MS-DOS Assemblers Compared
- "Perhaps the greatest (though most overlooked) feature added to version
5.10 was the @@ local label; we no longer had to come up with a unique label
for each conditional test. Note that Microsoft's @@ labels are not the same as
TASM's. Microsoft included a text editor simply named M, which a few
programmers loved, but many never figured it out at all. Version 5.10 also
added OS/2 1.x support."
REFERENCE: r_harvey
-
"New with 5.1 is the Microsoft Editor, a programmer's editor that allows compiling (or assembling) from the
editor. One major feature of MASM is a BIND utility, which allows the creation of a program that runs under
DOS or OS/2."
REFERENCE: Dr. Dobb's
-
According to a BYTE magazine "Programmer's Paradise" advertisement from June of 1990,
Microsoft Macro Assembler (presumably version 5.1) had a list price was $150,
although sold for $105; much less than the C compilers. The competition between
Microsoft and Borland was evident as the list and sale prices between MASM and Turbo
Assembler were identical. In an ad in the November 1990 BYTE magazine, Turbo Assembler 2.0
was bundled with Borland's Turbo C++ Professional, implying the Turbo Assembler at the
time was 2.xx; this is further verified by the command line copyright dates of
Turbo Assembler 2.xx.
MASM 5.1 3-Hole "Technical Highlights" Card / Brochure
|
|
|
|
MASM 5.10A © 1981, 1989 (a.k.a. 5.1A) |
MASM.EXE | 110,937 bytes (108k) | md5=03671c1240696672ef413817c62a8e6e | date=1/16/1989 11:10am | | (file date from EXE offset 1A50B / DOS) | | [Command Line] |
MASM.EXE | 110,675 bytes (108k) | md5=331bbd30a4da6068884c19b89921c6d9 | date=7/22/1988 2:28pm | | (file date from EXE offset 1A419 / DOS) | | [Command Line] |
MASM.EXE | 124,448 bytes (122k) | md5=20ca57a959cd487ddb1eeeafd3f99964 | date=11/19/1991 10:55am | | (From Win3.1 DDK / Dual Mode) | | [Command Line] |
MASM.EXE | 124,448 bytes (122k) | md5=910b3486b43acf67452fa1e186e95529 | date=3/18/2002 5:54pm | | (From WS03 SP1 DDK / DOS) | | [Command Line] |
|
@Version reports: 510
The directory listing (and
README.DOC)
from the 360k distribution disk is as follows
(courtesy of pcjs.org):
Volume in drive A is MASM-5-10A
Directory of A:\
MASM EXE 110937 01-16-89 11:16a
BINB <DIR> 03-19-90 12:15p
README DOC 3951 03-10-90 4:06p
3 file(s) 114888 bytes
Directory of A:\BINB
. <DIR> 03-19-90 12:15p
.. <DIR> 03-19-90 12:15p
MASM EXE 124448 01-16-89 11:11a
3 file(s) 124448 bytes
Total files listed:
6 file(s) 239336 bytes
120832 bytes free
It is interesting to note that while the timestamp in the DOS version of MASM.EXE in the listing
above (not the one in BINB) has a date of 11:16am, the internal timestamp is 6 minutes prior, containing
11:10am; at least in the version I have to compare it to.
This version of MASM, known as an "incremental update", was released at least as early as the Windows 3.1 DDK (located
in "286\tools") but has variations that date back to 1988.
Since the Windows 3.1 DDK, this version was again released nearly 11 years later in 2002 with the Windows Server 2003 SP1 DDK 3790.18030 located in "WINDDK\3790.1830\bin\bin16".
This was primarily a bugfix release including the fix described in
MASM KB Article Q32811. It is puzzling that a 5.1 series
assembler shipped with the WS03 DDK rather than one of the 6.x versions as the "16-bit assembler". Also
interesting is the fact that 5.10A was chosen over 5.10B which may indicate version 5.10B was a special hack just for Windows 3.1.
The changelist below was derived from the
README.DOC.
CHANGELIST:
MASM5.EXE | 111,396 bytes (109k) | md5=562f09d9136f12bf9eb15d5cde2e15d1 | date=1/4/1992 12:52pm | | (file date from EXE offset 1A6CB is 4/7/1989 11:50) | |
|
@Version reports: 510
This version came with the Windows 3.1 DDK, located in the "386\tools" directory.
According to Microsoft KB 110405, version 5.10B
was designed for the Windows 3.1 DDK.
The DDK's DRIVERS.TXT file explains that MASM5.EXE (5.10B) is for 386 virtual devices.
WHAT OTHERS HAVE SAID:
- "The best traditional MASM was 5.10B, which has been around since 1989.
While reliable, fast and small, it didn't have high-level structures (.IF /
.ENDIF), and a few 386 instructions were encoded a bit oddly. It was the last
version that would run in less than 640K and fit on a low-density floppy disk.
Version 5.10B was available on the first pre-release Microsoft Developer's
Network CD-ROM (dig around, it's buried in there somewhere)."
QuickAssembler © 1989-1990 |
In 1989 Microsoft released QuickAssembler, a scaled-down likeness of MASM that was bundled with QuickC, a scaled-down version of
the Microsoft C compiler.
QuickAssembler was limited to producing only 16-bit DOS programs targeting the Intel 286 processor and below.
386-specific code or protected mode programming under Windows or OS/2 required the full-featured MASM.
While this product had its own code base, it was compatible with the current MASM 5.xx syntax
and likely shared some of the same code with MASM as an official variant. It was implemented not as a standalone EXE, but as a
DOS overlay (within the file QAS.OVL) loaded by the QuickC editor QC.EXE.
Microsoft's relatively short-lived "Quick" language products were to compete with Borland's widely popular "Turbo" language
products featuring an IDE (integrated development environment) facilitating ease of development especially for beginner programmers.
In contrast, Microsoft's languages until this point targetted primarily businesses and professionals, were more difficult to use
and relied upon separate and distinct programs to perform the editing, building, and debugging steps necessary in software development.
Shortly after QuickC 2.0 added inline-assembly features to its C Language in January of 1989,
QuickAssembler made its debut that summer alongside the next installment of QuickC, version 2.01,
for a combined price tag of $199. QuickAssembler shared the same integrated development environment as QuickC,
but could edit, build and debug standalone programs written in either C or pure assembly language depending on the source file's extension.
This DOS-based IDE would eventually become known as the Programmer's Workbench, being bundled with
the next major release of MASM in version 6.0.
Despite its IDE having rudimentary features by comparison to Borland's,
Microsoft eventually caught up in the late 1990s with the feature-rich and upcoming Visual Studio as the dominant IDE for Win32 programming.
QuickAssembler was bundled with the following DOS-based versions of QuickC below.
This product was abandoned by the next and final release of QuickC, version 1.0 for Windows in September of 1991.
(the predecessor to Microsoft Visual C++).
- QuickC with QuickAssembler 2.01: released in June 1989 (README.DOC)
- QuickC with QuickAssembler 2.50: released in May 1990 (README.DOC)
- QuickC with QuickAssembler 2.51: released in 1990 (README.DOC)
Article: Microsoft Preparing to Unleash Quick Blitz of Language Products InfoWorld - May 15, 1989 |
|
|
|
Article: Quick Assembler Bundled With Microsoft's Quick C InfoWorld - June 12, 1989 |
|
|
|
MASM386 5.NT.02 © 1981, 1989 (a.k.a. 5.10.NT) |
MASM386.EXE | 211,556 bytes (207k) | md5=1e673dbfa68e9d1431869c57f2f8c48c | date=11/1/1993 6:28am | build 3.10.508.1 | (from Win32 SDK for NT 3.1 - \MSTOOLS\BIN\i386) | | [Command Line] |
MASM386.EXE | 153,360 bytes (150k) | md5=3ebda9cebf3aec0626816e89f3cfa012 | date=9/4/1994 1:07am | build 3.50.794.1 | (from Win32 SDK for NT 3.5, Final, Sep 1994 - \MSTOOLS\BIN\I386) | | [Command Line] |
MASM386.EXE | 258,560 bytes (252k) | md5=661bee6835e90f66c1585504ac250907 | date=12/3/1991 1:54am | | (from MSDN Win32 DDK CD for NT 3.1 Build 1.239.1 / untested) | |
|
@Version reports: 510
MASM386 (i.e. the 5.NT series MASM) was a special 32-bit version that only ran under NT and OS/2 (no DOS support).
This version was clearly the earliest of all 32-bit versions of MASM, especially given that it supported building
32-bit targets without the use of the "flat" model!
It first shipped with the Windows NT 3.1 Win32 SDK for use with the DDK (Driver Development Kit).
MASM386 was a fork of the 5.1 code, modified to run and assemble under the 32-bit NT 3.1 and 3.5 operating
systems (a 32-bit kernel with the UI of Windows 3.1), but before Microsoft had stabilized the MASM 6.x code branch.
[bytepointer.com edit] Courtesy of the various NT source code leaks over the years,
an internal MASM 5.NT README
has surfaced along with the MASM386 source code (which isn't available here).
According to this document, the 5.NT series was officially:
- A forked of the 5.10A version
- The first NT-portable version now compatiable with Microsoft's internal NT build environment; i.e. all the DOS hacks and other x86 specific
assembly code was replaced with portable C-Runtime calls allowing platform portability. This was initially achieved on both
the x86 and MIPS platforms.
- Missing features such as floating point initializers and the MS floating point data format (i.e. no support for the .MSFLOAT directive)
- The timestamp formats displayed in listing files were changed to use the standard format provided by the C runtime libraries.
Although the file timestamps range between 1991 and 1993 for the publicly released 5.NT.02 version, the copyright year is 1989.
1989 likely marks the beginning of the 5.NT series (i.e. version 5.NT.01). It remains unknown if the 5.NT.01 version was ever released publicly.
The oldest version of 5.NT.02 listed here is from December 1991 and happens to be the only 32-bit MASM I've encountered that won't run on Windows XP and up
(MessageBox "not a valid Win32 application" followed by console message "Access is denied.").
The executable module has some invalid fields (virtualsize for the sections are zero), relocation table in an unknown format, and a host
of other problems indicative of the fact that the program was built before the PE/COFF specification was finalized. I did not bother
to install an NT 3.1 to see if I could get it to work, so I've got it listed as "untested".
The \DDK\DOC\README.DDK file mentions only supporting this version of MASM as version 6.x
had not been tested enough for use with the DDK:
* Intel x86 assembler code
If the Win32 SDK is not installed or in the path, it is necessary to
copy the masm386 binary from the Win32 SDK if assembly code is used in
a driver targeted for the Intel x86 platform. This is required to
build some of the video drivers for x86 such as the VGA display
driver. The masm386.exe binary should be copied from the
\mstools\bin\i386 directory of the SDK to the \<ddkroot>\bin directory
where the DDK is installed.
It may also be possible to use other 32bit Intel x86 assemblers (such
as Microsoft MASM 6.x) but the DDK is not tested with other assemblers
and code changes may be required.
The version resource within MASM386.EXE contains (note the funny mixed-case with the Internal Name):
File version: 3.10.508.1
Description: Microsoft Assembler
Copyright © Microsoft Corp. 1981-1993
Company: Microsoft Corporation
Internal Name/Original File name: MAsm386.Exe
Language: Language Neutral
Product Name: Microsoft® Windows NT(TM) Operating System
Product Version: 3.10
The only other piece of documentation from the DDK was the MASM.TXT file, mostly explaining differences between this version of MASM and
the 6.x series.
CHANGELIST:
-
5.1 as a 32-bit assembler:
[bytepointer.com edit] MASM 5.1 turned into a 32-bit hybrid assembler for NT 3.x
-
Introduction of the .FPO directive:
.FPO controls the emission of debug records to the .debug$F segment or section.
The README.TXT from version 6.11,
the README.TXT from version 6.11a
and the README.TXT found in version 6.11d
all document the .FPO directive as being present in MASM386 and initially for the 6.x series
in version 6.11a. The .FPO directive was not supported in any other 6.x release.
The .FPO directive would be re-introduced in version 8.0 for reasons that are unclear.
WHAT OTHERS HAVE SAID:
-
"Microsoft's early 32-bit development tools often included a descendent of the 5.10 series, usually called
MASM386.EXE. The latest was labeled "5.NT.02" and responds as @Version=510. It's really primitive when
compared to MASM 6.x."
REFERENCE: r_harvey
ML.EXE | 244,690 bytes (239k) | md5=6b9ac50cd937732fdbd328d7f4f1431e | date=4/3/1991 2:59pm | | | |
ML.EXE | 225,863 bytes (221k) | md5=ac746c41188ab43aaf3a5a5097909e68 | date=4/3/1991 2:58pm | | (OS/2 version / untested) | |
|
@Version reports: 600
Retail Price: $150.00 / Upgrade Price: $75.00
This version of MASM introduced support for the 80486 (i486) processor released by Intel in April of 1989.
Version 6.0 shipped the week of April 29th 1991 (see InfoWorld magazine article below).
The 4-floppy distribution (on 1.2 MB 5¼ inch disks) included a
PACKING.LST file on the first disk
along with a README.DOC file.
On July 1, 1991, Dr. Dobbs published a good primer article for version 6.0, called
Masm's Changing Face.
Most of the information below was derived from the 6.0 programmer's guide and other official
sources (unless otherwise noted):
SYSTEM REQUIREMENTS:
- A personal computer running DOS version 3.0 or later or OS/2 version 1.1 or later.
- 640K (kilobytes) of available memory (RAM) for operating under DOS (1 megabyte of RAM recommended)
- 3 megabytes of RAM for operating under OS/2 (4 megabytes are recommended)
- At least 384K of extended memory if you want to debug large DOS programs.
- A hard-disk drive with at least 4 megabytes of free space. (The actual space required depends on the
options you select.)
- A floppy-disk drive.
MINIMUM SYSTEM REQUIREMENTS FOR ASSEMBLED PROGRAMS:
- Programs assembled with MASM version 6.0 run under DOS versions 2.1 and later.
CHANGELIST:
-
Support for the Intel 486 (80486) processor instruction set:
- The .NO87 directive disables all coprocessor instructions
-
MASM can assemble instructions specific to the 80486, enabled with the .486 directive. The
.486P directive enables 80486 instructions at the highest privilege level (recommended for
systems-level programs only).
-
New 486 processor instructions supported:
BSWAP | - Byte swap |
CMPXCHG | - Compare and exchange |
INVD | - Invalidate data cache |
INVLPG | - Invalidate Translation Lookaside Buffer entry |
WBINVD | - Write back and invalidate data cache |
XADD | - Exchange and add |
-
Support for the 32-bit flat memory model:
In the flat memory model (available only in version 2.0 of OS/2), segments may be as large as four
gigabytes because offsets contain 32 bits instead of 16. Segments are limited to 64K in all other memory
models supported by DOS and earlier versions of OS/2. Version 2.0 of OS/2 runs only on 80386/486
processors.
[bytepointer.com edit] Although this was the first official version supporting the flat memory model, it was only available for OS/2 version 2.0.
Flat Model support for Windows NT was not yet available.
-
Operating Systems Support:
Specifying the new OS_OS2 or OS_DOS keywords in the .MODEL statement allows the new .STARTUP directive
to generate start-up code appropriate for the language and operating system. The new .EXIT directive
generates the appropriate exit code.
-
New OS/2 Features:
Create OS/2 applications with increased support for dynamic-link libraries (DLLs), multiple threads, and
improved debugging options.
[bytepointer.com edit] Added support for the SYSCALL calling convention (for all OS/2 version 2.0 functions).
-
Direct support for .COM files:
[bytepointer.com edit] Jump to the 5.0 COM sample on this page to see just how tedious
creating a COM file used to be. This was for two reasons: 1. the source code for a COM file didn't support simplified segment
directives; 2. you had to assemble, link (creating an unusable EXE file) and then use EXE2BIN from
your DOS distribution to generate the final COM file; 3. after all of this, debugging a COM file wasn't
possible either because you couldn't embed symbolic debugging information in them.
Microsoft KB24954: Producing .com Files
With MASM explains the new and better way to create COM files, new for version 6.0:
The Microsoft Macro Assembler packages prior to version 6.0 cannot produce .com files without an
additional utility. One such utility is EXE2BIN, which is included with MS-DOS. It can convert .EXE
files which have only one segment and an origin of 100h to .COM files. For more information on this
utility, refer to your DOS manuals or contact the company which supplied your version of MS-DOS.
MASM version 6.0 is the first version of the assembler to support
the tiny model. Use the following steps the produce a .com file in MASM 6.0.
- Use .model tiny. Declare logical segments using the simplified segment directives or full segment declarations.
-or-
Do not use the .model directive and assemble with /AT. Use full segment declarations.
- Make sure that the first statement in the the code segment is ORG 100h.
- Build the .com file.
Compiling and linking in one step: If .model tiny was used, no options are needed. The
linker will automatically receive the /TINY switch, the file extension on the file produced
will be .com, and the executable is indeed a .com file.
-or-
Performing a separate link: Specify the /TINY option on the link command line. The linker
will issue the following harmless warning
L4045: name of output file is 'filename'
where 'filename' will have a .com extension.
[bytepointer.com edit] The COM file sample from the 5.0 manual now
looks like the following after modifying the source code to take advantage of the 6.0 COM file
enhancements (and removing the comments):
.MODEL tiny
.DATA
message DB "Hello, world.",13,10
lmessage EQU $ - message
.CODE
ORG 100h
start: mov bx,1
mov cx,lmessage
mov dx,OFFSET message
mov ah,40h
int 21h
mov ax,4C00h
int 21h
END start
The source code is much more elegant. Now, to build it with version 6.0, run the following commands:
ml /AT /c example.asm
link /tiny example.obj,example.com;
The linker then produces a 33-byte COM file. This is 3 bytes less than the 5.0 version sample that
resulted in a 36-byte COM file.
-
Specifying 16-Bit and 32-Bit Instructions:
MASM supports all instructions that work with the extended 32-bit registers of the 80386/486. For
certain instructions, you can override the default operand size with the W (word) and the D (doubleword)
suffixes.
-
Introduction of the HIGHWORD and LOWWORD Operators:
These new operators return the high and low words for a given 32-bit operand. They are similar to
the HIGH and LOW operators of MASM 5.1 except that HIGHWORD and LOWWORD can take only
constants as operands, not relocatables (labels).
-
MASM.EXE replaced by ML.EXE (MASM.EXE now just a compatibility driver for version 5.1 sources):
MASM.EXE is now ML.exe: prior to version 6.0, the Microsoft Macro Assembler was MASM.EXE. Since
version 6.0, it has been replaced by the more powerful and flexible ML.EXE using different
command line options, such as allowing an assembly and link with a single command. MASM.EXE
does remain, recognizing the old MASM driver command syntax to support existing batch files and
makefiles prior to version 6.0. Internally, MASM.EXE translates command-line options to those
accepted by ML.EXE, and then calls ML.EXE. The ML command-line options are now case-sensitive and must be
separated by spaces.
-
Multiple Source Assembly:
Although this was not mentioned in the manual's changelist, version 6.0 was the first version of MASM
that could assemble more than one file in a single invocation from the command line while prior versions
only supported assembly of a single file at a time. According to the InfoWorld article [see below] on
April 29, 1991 (MASM 6.0 Changes), MASM's command line additionally supported wildcards.
-
Search order for include files:
The search order for includes is
different than simply looking in the current directory. MASM now
searches for include files in the directory of the main source file.
Similarly, MASM searches for nested include files in the directory
containing the include file. Additional paths can be specified with
the /I command-line option.
-
n-pass Assembler:
When possible, MASM now performs assembly in a single pass, caching the source file in RAM and avoiding
reading the file twice from disk.
MASM 5.1 always assembled in two source passes. Because MASM now 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 now 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 rewrite the
affected code, since OPTION M510 does not enable this behavior. Pass-sensitivity was normally used in
version 5.1 in the following situations, and are no longer
necessary in version 6.0:
- Declaring an external variable only if it is not defined in the current module
- Including a file of definitions only once to speed assembly
- Generating an %OUT or .ERR message only once
- Generating an error if a symbol is not defined but may be forward referenced
-
Support for the LROffset operator:
For compatibility with applications for Windows, the LROFFSET operator can calculate a relocatable
offset, which is resolved by the loader at run time.
This allows the Windows memory manager to relocate code segments as neeeded.
-
Expanded high-level functionality and support for structures, unions and data types including
pointer, signed and floating point types:
-
Type Initializers:
You can now use the same type specifiers in initializations as in other contexts such as
to define/initialize variables using BYTE, SBYTE, SWORD, and SDWORD, rather than simply DB.
-
Support for Signed Types:
You can now use the SBYTE, SWORD, and SDWORD directives to declare signed data.
-
Support for Floating-Point Types:
You can now use the REAL4, REAL8, and REAL10 directives to declare floating-point variables.
-
Type definitions can now include distance and language type attributes:
Procedures, procedure prototypes, and external declarations now let you specify the type as a
qualified type.
-
The syntax for defining and using structures and records has been enhanced:
- Structures can be nested.
- The names of structure fields need not be unique. As a result, you must qualify
references to field names.
- Initialization of structure variables can continue over multiple lines provided the last character in the
line before the comment field is a comma.
- Curly braces and angle brackets are equivalent. For example, this following code works:
SCORE STRUCT
team1 BYTE 10 DUP (?)
score1 BYTE ?
team2 BYTE 10 DUP (?)
score2 BYTE ?
SCORE ENDS
first SCORE {"BEARS", 20, ; This comment is allowed.
"CUBS", 10 }
mov al, [bx].score.team1 ; Field name must be qualified
; with structure name.
- Support for the definition of unions with the UNION directive.
- Support for types (defining your own types), including pointer types, with the new TYPEDEF directive
for later use in the program
-
Introduction of the SIZEOF operator:
- When applied to a type, SIZEOF returns the size attribute of the type expression.
- When applied to a data label, SIZEOF returns the number of bytes used by the initializer in
the label's definition. In this case, SIZEOF for a variable equals the number of bytes in the
type multiplied by LENGTHOF for the variable. The LENGTHOF operator returns the number of data
items allocated for a data label.
-
Support for identifier names of up to 247 characters:
All characters are significant, whereas
under version 5.1, names are significant to 31 characters only.
- Support for multiple-line initializers:
A comma at the end of a line (except in the comment field) implies that the line continues. E.g.:
longstring BYTE "This string ",
bitmasks BYTE 80h, 40h, 20h, 10h,
08h, 04h, 02h, 01h
-
Support for comments in extended-lines:
Earlier versions allow a backslash ( \ ) as the line-continuation character if it is the last nonspace
character in the line. MASM now permits a comment to follow the backslash.
-
New Predefined Symbols:
The following new predefined symbols (also called predefined equates) provide information about simplified
segments:
Predefined Symbol | | Value |
@stack | | DGROUP for near stacks, STACK for far stacks |
@Interface | | Information about language parameters |
@Model | | Information about the current memory model |
@Line | | The source line in the current file |
@Date | | The current date |
@FileCur | | The current file |
@Time | | The current time |
@Environ | | The current environment variables |
-
Renamed Directives:
Although MASM still supports the old names in MASM 5.1, the following directives have been renamed for
language consistency:
MASM 5.1 | RENAMED TO |
DOSSEG | -> .DOSSEG |
.LFCOND | -> .LISTIF |
.XALL | -> .LISTMACRO |
.LALL | -> .LISTMACROALL |
.XCREF | -> .NOCREF |
.XLIST | -> .NOLIST |
.SFCOND | -> .NOLISTIF |
.SALL | -> .NOLISTMACRO |
%OUT | -> ECHO |
EXTRN | -> EXTERN |
IRP | -> FOR |
IRPC | -> FORC |
REPT | -> REPEAT |
STRUC | -> STRUCT |
SUBTTL | -> SUBTITLE |
[bytepointer.com edit] %OUT was not only changed to ECHO, but ECHO could expand predefined text macros such as
@Version as in the example below making it more handy for debugging. %OUT was not capable of this
this expansion.
;works on MASM 6.0 and up
%ECHO MASM reports its version as: @Version
-
New OPTION directive:
The OPTION directive allows you to selectively define the assembler's behavior, including its
compatibility with MASM 5.1.
-
5.1 Compatibility Mode:
MASM provides a "compatibility mode," making it easy for you to transfer existing MASM 5.1 code to
the new version. You invoke the compatibility mode through the OPTION M510 directive or the /Zm
command-line switch. In some cases, OPTION M510 does not support MASM 5.1 behavior. In several
cases, this is because bugs in MASM 5.1 were corrected. If you have conflicts between identifier
names and new reserved words use the "OPTION NOKEYWORD" to resolve errors generated from the use of
reserved words as identifiers.
-
User-Defined Prologue/Epilogue:
Support for user-defined stack frame setup (prologue) and cleanup (epilogue) code VIA macros and
the OPTION directive. The prologue code generated immediately after a PROC statement sets up the
stack for parameters and local variables. The epilogue code handles stack cleanup.
-
Enhancements to the ASSUME directive:
MASM now automatically generates ASSUME values for the code segment register (CS) when a segment is
opened. It is no longer necessary to include lines such as
ASSUME CS:MyCodeSegment
in your programs.
In addition, the ASSUME directive can now include ERROR, FLAT or register:type. Generating ASSUME
values for the code segment register CS to be other than the current segment or group is no longer
valid.
-
The .STARTUP and .EXIT directives:
These directives automatically generate appropriate startup and exit code for
your assembly-language programs.
-
The PUSHCONTEXT and POPCONTEXT directives:
PUSHCONTEXT saves the assembly environment, and POPCONTEXT restores it. The environment includes the
segment register assumes, the radix, the listing and CREF flags, and the current processor and
coprocessor. Note that .NOCREF (the MASM equivalent to .XCREF) still determines whether information for
a given symbol will be added to Browser information and to the symbol table in the listing file.
-
MASM now generates complete CodeView information for all types:
-
PTR and CodeView:
Under MASM 5.1, applying the PTR operator to a data initializer determines the size of the data
displayed by CodeView. You can still use PTR in this manner, but it does not affect CodeView
typing. Defining pointers with the TYPEDEF directive allows CodeView to generate correct
information.
-
More powerful features for declaring and calling procedures:
-
The extended PROC syntax for generating stack frames has been enhanced since version 5.1.
-
Introduction of the PROTO directive:
PROTO lets you prototype procedures in the same way as high-level languages.
PROTO enables type-checking and type conversion of arguments when calling the procedure with INVOKE.
-
Introduction of the INVOKE directive:
INVOKE automatically generates code to pass arguments (converting them to a related type, if
appropriate) and call a procedure according to the prototype and specified calling convention.
MASM also provides the VARARG keyword to pass a variable number of arguments to a procedure
with INVOKE.
-
Introduction of the ADDR keyword:
When used with INVOKE, it changes an expression to an address expression for passing by
reference instead of value, in the same way as the address-of operator (&) in C.
-
Simplified methods for applying public attributes to variables and routines in multiple-module programs
making it easier than in version 5.1. The EXTERNDEF and PROTO directives make it easy to maintain all
global definitions in include files shared by all the source modules of a project.
-
Introduction of the EXTERNDEF directive:
MASM 5.1 requires that you declare public and external all data and routines used in more than
one module. A single EXTERNDEF directive now accomplishes the same task. EXTERNDEF lets you put
global data declarations within an include file, making the data visible to all source files
that include the file.
-
Specify Alternate Symbol Names for the Linker:
The syntax for EXTERN allows you to specify an alternate symbol name, which the linker can use
to resolve an external reference to an unused symbol preventing linkage with unneeded library
code.
-
Case Sensitivity adherence to Langtype:
In MASM 5.1, sensitivity to case is influenced only by command-line options such as /MX, not the
language type given with the .MODEL directive (langtype). Now langtype takes precedence over the
command-line options that specify case sensitivity.
-
New directives for generating loops and decision statements:
-
Introduction of High-Level (C-like) Flow-Control Constructions:
Several new directives that generate code for loops and decisions depending on the status of a
conditional statement (tested at run time rather than at assembly time) include: .IF, .ELSE,
.ELSEIF, .REPEAT, .UNTIL, .UNTILCXZ, .WHILE, and .ENDW. The associated .BREAK and .CONTINUE
directives for loops and IF statements are also provided.
-
Support for automatic Jump Encoding Optimization:
MASM now automatically generates the smallest encoding for direct unconditional jumps. If a
conditional jump requires a distance other than SHORT, MASM generates the necessary comparison
and unconditional jump to the destination.
-
Better Jump Handling:
Better handling of the "Jump Out of Range" errors present in version 5.1 and earlier due to jump offsets
greater than 128 bytes.
REFERENCE: r_harvey
-
Enhancements for writing and using macros:
-
Required and Default Macro Arguments:
You can now specify default values for arguments or mark them as required
using the := operator or REQ respectively.
-
Introduction of the VARARG keyword:
MASM 5.1 ignores extra arguments passed to macros. Now you can pass a variable number of
arguments to a macro by appending the VARARG keyword to the last macro parameter in the macro
definition. The macro can then reference additional arguments relative to the last declared
parameter.
-
New Directives for Macro Loops:
You can implement loops inside of macros in various ways. For example, within a macro
definition, the new WHILE directive expands the statements in a macro body while a condition
remains true. The other macro loop directives IRP, IRPC, and REPT, have been renamed FOR, FORC,
and REPEAT.
-
The GOTO Directive for Macros:
Within a macro definition, GOTO transfers assembly to a line labeled with a leading colon(:).
-
Macro Functions:
You can define macro functions, which return text macros. Several predefined text macros are
also provided for processing strings. Macro operators and other features related to processing
text macros and macro arguments have been enhanced.
-
Introduction of the EXITM directive:
At assembly time, macro functions can determine and return a text value using EXITM.
-
Introduction of the TEXTEQU directive for text macros:
Text macros allow greater flexibility than EQU. For example TEXTEQU can assign to a
label the value calculated by a macro function.
-
Introduction of the following predefined text macro functions:
Predefined macro string functions concatenate strings, return the size of a string, and
return the position of a substring within a string.
@CatStr | - A concatenated string |
@InStr | - The position of one string within another |
@SizeStr | - The size of a string |
@SubStr | - A substring |
-
CodeView Debugger 3.12:
Track down program bugs and logic errors more quickly with the new Microsoft CodeView® debugger
version 3.12. With an 80286 or 80386 processor and 1 megabytes or more of RAM, you can debug a program
up to 640K in size in real mode.
-
New Tools Added:
-
Introduction of the Programmer's WorkBench (PWB):
The Programmer's Workbench offers an integrated development envieronment (IDE)
from which you can write, edit, debug, and execute code.
The PWB could be configured to edit, build and debug in many languages and also offers project
capabilities. Edit source code with PWB's mouse- and window-oriented editor.
Cross-reference program procedures with the PWB Source Browser.
[bytepointer.com edit] This was a DOS predecessor to the Visual C/C++ Editor "Visual Workbench"
that would be released about 2 years later, and then later renamed to "Visual Studio".
-
Introduction of the H2INC utility:
The program H2INC.EXE converts C include files to MASM include files. It translates data
structures and declarations but does not translate executable code.
-
The MAKE utility is replaced by NMAKE:
NMAKE provides new functions for evaluating target files and more flexibility with macros and
command-line options.
-
Introduction of the Microsoft Advisor System:
Access MASM language, assembler, linker, and utility documentation with the Microsoft Advisor and
QuickHelp online reference systems.
-
Removed Utilities:
- CREF was removed, but will be included once again in version 6.1 and finally in 6.11.
- EXEMOD
- EXEPACK
-
Command Line Changes:
[bytepointer.com edit] The command line options for version 6.0 and up were completely different than
the previous versions of MASM. This is one reason why Microsoft included the MASM.EXE compatibility
driver to invoke ML.EXE with the equivalent 5.1 options. One notable change is that you now have to issue
the /? switch to get a list of the available command line options. In previous versions of MASM this
was done with the /help (or simply /h) option. /h no longer works and /help will display the command
line options or bring up the QuickHelp utility (QH.EXE, if installed and set up properly).
WHAT OTHERS HAVE SAID:
- According to Windows Assembly Language & Systems Programming by Barry Kauler, Masm 6.0 was
not technically “Windows-aware” until at least version 6.1, but standalone Windows
applications could be built as long as the SDK was installed.
Article: MASM 6.0 Changes InfoWorld - April 29, 1991 |
|
|
Although apparently not publicly released, there were changes to this version that showed up in 6.00B.
WHAT OTHERS HAVE SAID:
- "This version was not released (didn't even escape). It fixed some macro
and structure alignment problems, and made @FileName always return an upper
case string (it had been returning whatever it found on the command line unless
you used wild cards)."
REFERENCE: r_harvey
ML.EXE | 250,074 bytes (244k) | md5=62d24aaca0b1373cf9e374703b3dc6ab | date=3/18/1992 5:31pm | | (file date from ML.EX$ on setup disk) | |
ML.EXE | 230,850 bytes (225k) | md5=f882dc9968c1cfd4219173994ad0ca6f | date=3/18/1992 4:40pm | | (file date from ML.EX$ on setup disk / OS/2 version / untested) | |
|
@Version reports: 600
Version 6.00B was the last version of MASM to be a pure 16-bit DOS application (and likely the last to support
OS/2), released just less than a year after 6.0. This didn't mean future versions wouldn't run under DOS, but
MASM would be a Windows hybrid executable allowing it to be run under DOS and NT simultaneously. This benefit
did not come without a cost however, as MASM's file size had to grow over 100k to accommodate addition of the
DOS Extender (see section MASM 6.1 below).
It is not known if this version was ever distributed as a patch, but for some, it was integrated directly into
the disk set "sold as" the retail 6.0 version.
The changelist below where unspecified was derived from the README.DOC.
CHANGELIST:
- 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.
- Added Stdcall calling convention switch (NOT from README.DOC). The /G command line option present in 6.0:
/G<c|d> Generate Pascal or C calls
Was changed to [add Stdcall] :
/G<c|d|z> Use Pascal, C, or Stdcall calls
NOTE: The Stdcall ("z" option) for the /G switch was not officially documented until version 6.1.
According to MSDN article Q94314 (below), the Stdcall feature was technically added in 6.00a, but since
6.00a wasn't publicly released, that information is being included here:
The Microsoft Macro Assembler (MASM) versions 6.0a and later support generating 32-bit flat memory
model code through the .MODEL flat directive. When combined with the CVTOMF and LINK32 utilities and
the KERNEL32.LIB library distributed with the Windows NT software development kit (SDK) or the LINK
utility and the KERNEL32.LIB library distributed with Microsoft Visual C++ for Windows NT, MASM can
generate a 32-bit flat memory model application for the Windows NT environment.
Because MASM version 6.0 does not properly support the _stdcall convention, it cannot be used to
generate applications for the Windows NT environment.
- 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.
WHAT OTHERS HAVE SAID:
- "MASM 6.00B fixed a few minor bugs missed in 6.00A. It was a fast,
versatile program. It was the last version that would run on any
Intel-compatible processor. I believe that it was also the last version that
officially supported OS/2. Microsoft sent copies of 6.00B free of charge to all
registered owners without saying a word about it. (Really! In fact, I bought
Windows 1.0, and later they sent me a free upgrade to 1.03; I haven't seen them
do that sort recently, though.) If you're running an older machine but want the
benefits of new-fangled Assemblers, this is your MASM."
REFERENCE: r_harvey
-
Vernon from pcdosretro (lead developer for IBM PC DOS 7)
had the following comment in response to this page previously reporting details from the Phoenix BIOS Developer's Blog
that early versions of MASM 6.x were "buggy":
"By the way the comment about the MASM 6.x series being pretty buggy until 6.14 is just not true.
As an assembly language programmer I have used MASM extensively since 4.0 and found that 6.00B (I never used
the original 6.0) was a MAJOR step up from previous versions in terms of stability and consistency and it
had very few bugs. The only bugs I can think of in 6.00B were an occasional extra tab in listings and
INVOKE/PROTO not always working as expected which was fixed in the 6.1x series."
ML.EXE | 360,480 bytes (352k) | md5=49790131ea2e38e1c14dc90111d3de33 | date=11/16/1992 4:00pm | | | |
|
@Version reports: 610
Retail Price: $199.00
MASM 6.1 shipped in January 1993. It was the first version to build Windows NT binaries (see InfoWorld article below)
and the first DOS/Windows hybrid version of MASM (importing KERNEL32.DLL and NTDLL.DLL). This was made possible
by the 3rd-party DOS Extender DOSXNT by Phar Lap Software, Inc. DOSXNT was required for MASM until the last
DOS version (6.11d), but is still required by Microsoft's last official 16-bit linker (5.60.339):
Lnk563.exe.
This was also the last version with printed manuals, although these manuals
were shipped with the later 6.11 version (the last retail box set). For this reason, even to this day, the
manuals are sought-after as they strill contain relevant information about the assembler. They are available in
PDF and DOC form on the internet as well as on MSDN.
After these manuals, Microsoft
began distributing MASM documentation exclusively by electronic means either with the MASM binaries themselves or alongside
the Visual C++ documentation on MSDN after version 6.15. Some of the relevant documentation files included with
this distribution include:
README.TXT (although the document is titled README.DOC),
ERRMSG.TXT,
CREF.DOC,
CV.TXT,
SMARTDRV.DOC,
and SAMPLES.TXT.
The following information unless otherwise noted was derived from the printed manuals:
SYSTEM REQUIREMENTS (from retail box shown below):
- Personal computer with a 386 or higher processor running MS-DOS operating system version 3.3 or later
- 4 MB of memory
- One high-density disk drive and a hard disk with 10 MB available (3.5" low-density disks available on request
CHANGELIST:
-
Flat memory model support for the new 32-bit Microsoft® Windows NT™ operating system:
Version 6.0 added the initial flat model support, but only for OS/2. Now MASM can build
32-bit binaries for Windows NT. The flat model allows segments as large as 4 gigabytes and offsets are 32
bits instead of 16 bits. All other memory models limit segment size to 64K for MS-DOS and Windows.
When you are creating a 32-bit application, you must link separately with a 32-bit linker. To prepare
your object files for 32-bit linking, assemble using the following switches:
- /c (assembles without linking)
- /coff (causes object files to be created in Windows NT-compatible common object file format)
After assembling, link with your 32-bit linker.
To build NT binaries, a specialized linker available in the WinNT 3.5 SDK was needed
REFERENCE: OSDEV MASM
Wikipedia's Entry for Phar Lap
mentioned the following about the NT compatibility of ML.EXE:
"Unfortunately, MASM 6.1 and the 16-bit version of the Visual C++ 1.0 compiler were Win32 applications written
for a beta version of Windows NT that was bound with the TNT DOS Extender, which means it could not run on the
final version of Windows NT until Beta2Fix.exe was run, which replaced all references to NTDLL.DLL with
BETA2.DLL. This was fixed in MASM 6.11 and Visual C++ 1.5."
-
Support for OS/2 Silently Removed:
[bytepointer.com edit] Although no official announcement was made, almost all references to OS/2 were removed from the 6.1
documentation (OS/2 was only mentioned on the copyright page, MS-DOS handling of the Critical Error flag, minimum
Intel processor types required for DOS and OS/2 operating systems, and some assembler and linker
errors). Likewise, the OS/2 BIND
utility was also removed. IMPLIB, a formerly OS/2-only utility now worked with Windows and NT DLLs, adding 2 new
command line options (/ntdll and /nowep).
Gordon Letwin's OS/2
usenet post titled: What's happening to OS/2 is an interesting read; an opinion from a Microsoft programmer
posted 8/17/1995 about why OS/2 was "doomed".
-
Support for PE/COFF formats:
MASM now supports producing object modules in the Portable Executable (PE/COFF) format, as required by
Windows NT.
-
Introduction of MLX.EXE, the DOS-Extended Assembler:
MLX allows the assembler to run in protected mode using one of the following drivers: DPMI, VCPI and
XMS. It is meant as a replacement for ML.EXE only if running ML with the /VM virtual-memory option
fails due to an out of memory error as ML.EXE with the /VM option runs significantly faster than MLX due
to its use of real mode. Also, MLX can only assemble one file at a time.
-
ML.EXE now a 32-bits:
ML now runs in 32-bit protected mode under MS-DOS, giving it direct access to extended memory for
assembling very large source files.
-
Windows Aware:
A collection of tools lets you write a dynamic-link library (DLL) for the Microsoft® Windows™
operating system without the Windows Software Development Kit. The LIBW.LIB library provides access to
all functions in the Windows application programming interface (API), so your DLL can display menus,
dialog boxes, and scroll bars. DLLs are compatible with the Visual Basic programming system.
-
Support for Instruction Timings:
Program listings now support displaying instruction timings. The number of required processor cycles
appears adjacent to each instruction in the listing, based on the selected processor.
-
CodeView Debugging:
Version 6.1 generates debugging information for CodeView version 4.0 and later.
-
Greater compatibility with version 5.1 than MASM 6.0:
Many programs written with version 5.1 will assemble unchanged under MASM 6.1. The OPTION M510
directive (or the /Zm command-line switch) assures nearly complete compatibility between MASM 6.1 and
MASM 5.1.
-
CMP byte-register Encoding Change:
MASM 6.1 uses a different encoding for the CMP <reg8>,<reg8> instruction than MASM 6.0 did.
There is no difference in length or processor timing.
-
Command Line Options Added:
/G | -  | New "z" option for Stdcall (this was fully
or partially supported in 6.00B, but not documented until now) |
/coff | -  | Generate COFF format object file |
/Sc | -  | Generate timings in listing |
@<file> | -  |
Response Files:
Information on response files is not included in the MASM 6.1 manuals;
however, this information can be found in "ML Command Line Options"
in Online help.
[bytepointer.com edit] What this means is that this useful feature is not documented anywhere but
the now obscure QuickHelp utility. To get this running, navigate to the BIN directory containing ML.EXE.
Ensure your PATH environment variable is set to the HELP directory installed with the distribution.
Run "ml /help". QuickHelp will pop up with a "ML Command-Line Syntax" page. About midway through
the page, select "ML Options". The first item in the next page is the "@<file>" switch for
response files. Select this option to display the details.
|
Command Line Options Removed:
/Fb | - Generate bound executable |
/VM | - Enable virtual memory |
-
New WIN.INC Include File:
Rather than have people attempt to convert WINDOWS.H to a MASM include file with the
H2INC utility, Microsoft provided one named
WIN.INC.
The reason was that WINDOWS.H had to be tweaked a bit prior to running through H2INC. The nice thing is
that all of the tweaks are explained in detail at the top of the file should you want to create your own
or use the same techniques for other header files.
-
CREF:
The CREF utility, missing since version 5.1 is back and is updated for the MASM 6.x series.
CREF will be distributed once more as part of MASM's last retail release in version 6.11.
This CREF details can be read in the
CREF.DOC.
Article: MASM 6.1 Update InfoWorld - December 14, 1992 |
|
|
MASM 6.1 3.5 Disk Set and Manuals (with 6.11 disks) |
|
|
ML.EXE | 360,992 bytes (353k) | md5=dd344d3f0162badea58ae801ca287b63 | date=3/12/1993 1:59pm | | (Date from patch README, but unconfirmed if correct) | |
|
@Version reports: 610
This was oddly the only version of MASM in the 6.x series that did not have a dependency on the ML.ERR
file (error message strings). For this reason, I suspect it evolved internally from a 5.1 series code fork.
The README.TXT distributed with the patch is the source of
changelist information shown below.
PATCH INFO:
-
DISTRIBUTED AS PATCH (61PTCH.ZIP) for version 6.1 (reportedly posted on the Microsoft BBS).
AFFECTED FILES: 10 (7 changed, 3 added)
- CHANGED: ML.EXE, MASM.EXE, CVTOMF.EXE, DOSXNT.EXE, NMAKE.EXE, PWBC.XXT, PWBUTILS.MXT
- ADDED: CNOCRTDW.LIB, BSCMAKEV.EXE, PWBPROF.XXT
CHANGELIST:
-
Compatibility problems with Microsoft Visual C++:
-
MASM 6.10 cannot be installed in the same directory as Microsoft Visual C++, because of DOS extender
conflicts. MASM 6.1a uses the same version of the DOS extender as Visual C++, eliminating this
problem.
NOTE: Microsoft Visual C++ contains newer versions of some utilities. To use the newer utilities,
ensure that Visual C++ comes before MASM on the path.
-
The MASM 6.10 PWB extensions use /NOF as an abbreviation for the "Translate Intrasegment Far Calls"
linker option. /NOF is not a legal option for the Visual C++ linker. To make PWB change /NOF to
/NOFA:
1. Open the desired project.
2. From the Options menu, choose Link Options.
3. Select Additional Debug Options or Additional Release Options.
4. Choose OK to close the Additional Options dialog box.
5. Choose OK to close the Link Options dialog box.
-
Inability to run MASM from a read-only network drive:
MASM now correctly uses the TMP environment variable to create swap files for virtual memory. If you
are running MASM from a read-only network drive, ensure the TMP variable is set to a drive and directory
for which you have write permission.
-
Bugs Fixed:
Errors when assembling a very large number of files using ML *.ASM have been fixed.
-
Added compact memory model Windows DLL library (CNOCRTDW.LIB):
CNOCRTDW.LIB is the compact memory model version of the Windows DLL startup code. Because Windows DLLs
rarely use the compact model, this file is not typically needed. To use CNOCRTDW.LIB, make sure it is
in the MASM libraries directory (for example, C:\MASM61\LIB).
-
Added virtual memory browser database utility (BSCMAKEV.EXE):
BSCMAKEV is a version of the BSCMAKE browser database utility which uses virtual memory. BSCMAKEV is
slower than BSCMAKE, but it can handle larger databases. To use BSCMAKEV, make sure BSCMAKEV.EXE and
BSCMAKE.EXE are in the same directory. BSCMAKE will automatically invoke BSCMAKEV when required.
-
Added PWB 2.1 extension for Microsoft Profiler (PWBPROF.XXT):
PWBPROF.XXT enables the use of the Microsoft Source Profiler version 1.0 with PWB. The PWB extension
originally supplied with version 1.0 of the Profiler is not compatible with the current version of PWB.
To use the Profiler with PWB, rename this file to PWBPROF.MXT and make sure it is in the same directory
as PWB (for example, C:\MASM61\BIN). The extension will automatically be loaded when PWB is run.
WHAT OTHERS HAVE SAID:
- "MASM 6.10A began shipping at the end of 1992. The A-release updated the
memory manager for compatibility with Microsoft's Visual C++ 1.0, and corrected
some memory management problems. Complaints from fuddy-duddies forced Microsoft
to revert to the old-style lea encoding. Unfortunately, 6.10A's wild card
support no longer worked reliably if you had more than about 180 files."
- "While memory requirements zoomed, MASM 6.10A was actually slower than
6.00B. If you had limitless memory, you could assemble limitlessly-large
files--though even version 5.10B could handle 300K files. In keeping with
Visual C++ 1.0, which could slurp-up over 50MB of disk space, everything about
MASM 6.10A grew--even the linker was over 300K. "
- "Version 6.10A shipped with the final update of the Programmer's WorkBench
(PWB) editor, which was like M with a user interface. If PWB's keyboard repeat
rate goes crazy, remove the Fastfunc lines from TOOLS.INI, or try the Microsoft
C/C++ 7.00 version (early 1992). The Visual WorkBench (VWB), a Microsoft
Windows editor in Visual C++ 1.0 (early 1993), replaced PWB. As of this writing
(March 2002), VWB and its make files are indifferent, if not hostile, to MASM.
Now, Microsoft's Visual Studio allows you to add any files to projects, even
MASM, if you manually set compile switches, and you have to set those switches
again for each additional file added to projects. If you use a lot of Assembly
files in a C/C++ project, expect a lot of fussing with dialog boxes to get it
all working together."
- "If you use complex, multi-line high-level directives in very large files,
you may experience "Line too long" errors that have nothing to do with the line
they reference. Shorten lines, even comment lines, within the high-level
structures until the errors go away. Running MASM from the DOS command line
instead of Microsoft Windows fixes many mysterious problems. The real fix will
appear seven years later."
REFERENCE: r_harvey
ML.EXE | 388,608 bytes (380k) | md5=0a05c3eae7888a2f01330862eeea7efd | date=9/24/1993 8:25am | | (Date from Setup File ML.EX$) | |
|
@Version reports: 611
Retail Price: $249.00
This version of MASM introduced support for the Pentium (i586) processor released by Intel on 3/22/1993.
pcjs.org has a directory
listing of this version's setup file (ML.EX$) with an alternative date of almost 1 day earlier than that
shown above at 9/23/1993 11:25pm.
This was the last retail version of MASM, and thus the last stand-alone product complete version (i.e. full set
of disks, not a patch). This version shipped with manuals from version 6.1.
This version's list price increased to a whopping $249.00 (the highest price for MASM to date).
According to Microsoft's MASM KB Article Q228454,
"MASM 6.11 is no longer available as a retail product." and further
indicating it could be ordered with a registered copy of Visual C++ or through some levels of MSDN.
The updated documentation files included with this distribution include:
README.TXT,
PENTIUM.TXT,
ERRMSG.TXT,
CV.TXT,
and SAMPLES.TXT.
MASM no longer had a dependency on NTDLL.DLL (as version 6.1 and 6.1a did), just KERNEL32.DLL (when running under NT).
SYSTEM REQUIREMENTS:
- Personal computer using a 386 or higher processor running MS-DOS
version 3.3 or later, Windows version 3.1 or later, or Windows NT
version 3.1 or later.
- 4 MB of available memory.
- Hard disk with 10 MB available space.
- One 3.5" high-density (1.44 MB) disk drive (3.5" low-density (720K)
or 5.25" high-density (1.2 MB) disks available separately with
coupon enclosed).
-
To target Windows 3.1, you need one of the following:
- Microsoft Windows Software Development Kit (SDK) 3.1.
- Microsoft Visual C++ Development System, Standard or Professional Edition.
-
To target Windows NT, you need one of the following:
- Microsoft Windows NT Software Development Kit (SDK).
- Microsoft Visual C++ Development System, 32-Bit Edition.
CHANGELIST:
-
New Pentium Directives:
- .586 - enables assembly of non-privileged instructions
- .586P - enables privileged instructions in addition to the non-privileged instructions
-
New Pentium Instructions:
The new instructions are extensions to the Intel486 instruction set:
CMPXCHG8B | - Compare and Exchange 8 Bytes |
CPUID | - CPU Identification |
MOV | - Move to/from Control Registers (CR0, CR2, CR3, CR4) to or from a general purpose register |
RDMSR | - Read from Model-Specific Register |
RDTSC | - Read from Time Stamp Counter |
RSM | - Resume from System Management Mode |
WRMSR | - Write to Model-Specific Register |
-
LEA instruction changes:
[bytepointer.com edit] This change made it into the previous version (6.1a) according to r_harvey, but officially documented in this
version.
The MASM 6.1 Reference indicates that the LEA instruction is encoded as a MOV when the source operand is
a direct memory address. In response to programmer requests, MASM 6.1x no longer performs this
optimization automatically. The optimization can be performed by using the OPATTR operator, as shown in
the following macro:
MOVLEA MACRO Dest, Symbol
IF (OPATTR(Symbol)) AND 08h
MOV Dest, OFFSET Symbol
ELSE
LEA Dest, Symbol
ENDIF
ENDM
-
.FPO Directive:
The .FPO directive controls the emission of debug records to the .debug$F segment or section. This
directive was originally included with MASM386 and is not supported by MASM 6.11. If you are using both
MASM 6.11 and MASM386, the following allows you to continue to implement the .FPO directive:
IF @version LT 600
.FPO
ENDIF
-
Linker Changes:
[bytepointer.com edit] The ALIAS directive is documented in the
README.TXT:
The ALIAS directive is not included in the printed documentation for MASM 6.11.
The ALIAS directive can be used for creating libraries that allow the linker (LINK) to map an old
function to a new function.
Syntax: ALIAS <alias> = <actual-name>
where alias is the alternate or alias name, and actual-name is the actual name of the function or
procedure. The angle brackets are required.
The ALIAS directive should be used with LINK 5.3 or later and LIB 3.2 or later. At this time, ALIAS
functions only with the 16-bit linker.
-
New /WIN32 switch to H2INC:
Use the /WIN32 switch with H2INC to convert C header files to NT-compatible MASM include files. When you
use the /WIN32 switch, C int data types are converted to the 4-byte assembler equivalent DWORD (signed
int data types are converted to SDWORD). Without the /WIN32 switch, H2INC converts int data types to
2-byte WORD (and signed int data types to SWORD).
[bytepointer.com edit] This version of H2INC crashes with the simplest of C header files (such as a single
#define, a single structure with two members, or even a file with nothing in it!) with or without the new
argument. It can however display its version header and command line help without crashing.
The version of H2INC that is released with the next version (MASM 6.12) does not crash in this
way. I have verified the crash on XP and DOSBox, although the crash under DOSBox results in a more
meaningful error:
DOSXNT : fatal error DX1020: unhandled exception: Page fault;
contact Microsoft Support Services
ProcessId=485 ThreadId=486
User Registers:
EAX=00000000h EBX=00000001h ECX=00000000h EDX=00000000h
ESI=00079963h EDI=00186F00h EBP=00186F5Ch ErrorCode = 00000004h
DS=0017h ES=0017h FS=005Fh GS=0017h FLG=00003246h
CS:EIP=000Fh:00068473h SS:ESP=0017h:00186ED4h
WHAT OTHERS HAVE SAID:
- Filename Wildcard Problem Fixed
REFERENCE: r_harvey
MASM 6.11 Complete Disk Set |
|
|
ML.EXE | 382,976 bytes (374k) | md5=58ab843e26f5b75197b4aab519c23ddf | date=3/21/1994 12:22pm | | (Date from Patch Files) | |
|
@Version reports: 611
Microsoft has documented this version as being a "maintenance release". The patch was previously available on
the Microsoft FTP site but it was taken down quite some time ago. Interesting they left all other 6.1x patches
except this one. Without jumping to conspiracy theories as to why, it is possible they removed this version
because it made use of "experimental" NT features that had since been solidified or removed in later versions
(such as the mysterious .FPO directive which disappears after this version only to be reimplemented in
version 8.0 approximately 11 years later).
This patch could be found however on the January 1995 Technet Supplemental CD and may have been available
up to the September 1995 edition.
The 6.11a README.TXT explains the changes, although
it seems the primary purpose for this version was the backwards-compatible support for the .FPO directive only previously
available under MASM386 5.10.NT (a 32-bit version for MASM for NT based on MASM 5.1).
Due to the MASM386 compatibility, I suspect this version was intended as the next upgrade from MASM386, bringing along the
bugfixes and new features of the MASM 6.x series to code that was most-likely stuck in version 5.1-land.
Microsoft KB article Q120920 (9/21/1994) "Visual C++ Vers 2.0 README.WRI, Part 4 Integrated Debugger" is
available on the "MSDN 97" help library, but does not seem to be available on the web. This article
references MASM 6.11a:
The Visual C++ version 2.0 debugger's Disassembly window may not display lines correctly if you are assembling
some modules of your Visual C++ application with Microsoft Macro Assembler (MASM) version 6.11 and using linker
version 2.50. To correct this problem, you should upgrade to the MASM version 6.11a maintenance release and
use the /COFF option on the ML command line.
The MASM version 6.11a maintenance release is available on the Microsoft Download Service (MSDL), phone
206-936-6735.
PATCH INFO:
-
DISTRIBUTED AS PATCH (ML611A.EXE / 323k) for version 6.11
AFFECTED FILES: ML.EXE, ML.ERR, H2INC.EXE, H2INC.ERR
LAST OFFICIAL DOWNLOAD LOCATION: ftp://ftp.microsoft.com/Softlib/MSLFILES/Ml611a.exe
CHANGELIST:
- MASM now supports structure packing on 8 byte boundaries as well as 16 byte
boundaries using the /Zp8 or /Zp16 switches. Older versions of Masm only
allowed up to /Zp4 structure packing.
-
New .FPO Directive:
FPO stands for Frame Pointer Omission. The .FPO directive is a feature added to MASM386 5.10.NT that
controls the emission of debug records to the .debug$F segment or section of the object file. These
records are the same records that the Microsoft Visual C++ 1.10 or Microsoft Fortran PowerStation
compilers emit when they perform frame pointer elimination under /Oy and /Ox optimization control,
respectively. Unlike the compiler, MASM never performs any such optimization. it simply passes on the
information supplied by the programmer within this directive to the object file.
The .FPO directive does not have to be used in order to debug assembly programs under the Microsoft
Visual C++ 1.10 or Microsoft Fortran PowerStation debuggers whether they are stand alone Windows NT
applications or mixed language C\Assembly or Fortran\Assembly Windows NT applications. This directive
has been implemented to provide better backward compatibility with assembly code written for MASM386
5.10.NT, which is provided with the Windows NT DDK.
The FPO directive should only be used on naked procedures or those procedures not declared with proto
and called with invoke. Also you do not need to use the .FPO directive to debug naked procedures or on
procedures that use proto and invoke.
The following 6 parameters are used within the directive as follows.
.FPO ( number of bytes in a procedures local variables divided by 4,
number of bytes in a procedures parameters divided by 4,
number of bytes in a procedure prologue,
number of registers saved by a procedures prologue,
If EBP is allocated,
Frame Type )
Parameters Range
---------- -----
number of bytes in local variables / 4 >= 0
number of bytes in parameters / 4 0 - 65535
number of bytes in the procedure prologue 0 - 255
number of registers saved 0 - 7
If EBP is allocated 0 = false, 1 = true
Frame Type 0 - 2
The valid values for the Frame Type parameter above are
FRAME_FPO 0
FRAME_TRAP 1
FRAME_TSS 2
The C compiler only generates entries with FRAME_FPO. The other two types are used inside the NT kernel
to all stack traces across trap and tss frames that can appear in ring 0 code.
Example Usages:
1)
aproc proc
.FPO ( 0, 0, 0, 0, 0, 0 ) ; all params are zero.
ret
aproc endp
2)
.code
push +000000001h
call aproc
add esp, 04h
ret
aproc proc
push ebp
mov ebp, esp
.FPO ( 0, 1, 3, 1, 1, 0 ) ; 0 = no locals
; 1 = 4 byte param \ 4
; 3 = bytes in procedure prologue
; 1 = one register saved in prologue
; 1 = if EBP was allocated
; 0 = frame type of FPO
mov eax, dword ptr [ebp+8] ; move the passed param to EAX.
leave
ret 00h
aproc endp
-
IMPLIED FIXES? (Removed from Known Assembler Bugs present in
README.TXT for version 6.11):
- Intersegment near jumps do not work across files (externs) in flat model.
When programming in flat mode, make sure that all intersegment near jumps
occur within the same file.
- The /link command line option for ML causes all following parameters to be
passed to the linker. If the /nologo command line option is passed to the
linker, the linker may parse other parameters incorrectly.
ML.EXE | 381,952 bytes (373k) | md5=5312c5bc214e2049d727fef15ad41ab5 | date=8/25/1994 6:30pm | | (from Win95 DDK) | |
|
@Version reports: 611
This version was shipped with the Windows 95 and NT 3.5 DDK's for building drivers. The short README.TXT
included said:
This directory contains upgraded MASM files. They are upgrades of
MASM 6.11, you will need to add these files to your MASM 6.11 directory.
These files are necessary for building VxDs for Windows 95.
Although there was no changelist, the official information available implied they added the bare-bones necessary
features (and bugfixes) that allowed drivers written for Windows 95.
What was said about MASM in the READVXD.TXT file from the Win95 DDK (see below) implied
this version was a pre-release/hotfix (or a downright hack). Supporting that theory, this version could NOT be patched by any of the
later 6.X patches that did patch the earlier 6.11 and 6.11a.
There does not seem to have ever been a 6.11b version mentioned or available to the public.
UPGRADE INFO:
-
DISTRIBUTED AS UPGRADE: exclusively with the Windows 95 DDK and Windows NT 3.5 DDK
AFFECTED FILES: ML.EXE, ML.ERR (to copy over previous versions in MASM 6.11 directory)
OFFICIAL INFO:
- According to the Win95 DDK README.TXT, "These files are necessary for building VxDs for Windows 95."
- V2CONV.TXT in the Win95 DDK said: "[MASM 6.11c] which fully supports COFF..." implying better COFF support
- READVXD.TXT in the Win95 DDK said: "Copy the contents of the MASM611C directory into your MASM6x\BIN
directory. These fixes will be included in the next release of MASM 6.X."
WHAT OTHERS HAVE SAID:
- "The 6.11C patch (er, upgrade) slipped-out in 1994. It added Windows 95
VxD support, but it was still 6.11 underneath. MASM's tendency to add extra
records to object files was corrected, which tamed object files to TASM and
WASM sizes. Borland's TASM was noticeably faster with large files."
REFERENCE: r_harvey
ML.EXE | 388,096 bytes (379k) | md5=cf70b409267a8f2085f00a4138b4628d | date=9/19/1995 1:18pm | | (Date from Patch File) | |
|
@Version reports: 611
This version was available as patch to be downloaded from Microsoft.
It was also bundled directly with the
Windows NT 3.51, Windows NT 4.0 and Windows 98 DDK's.
The ML.EXE found on the Windows NT 3.51 DDK had a date of 5/25/1995 6:57pm, about 4 months earlier than the
patch date.
This was the last version that ran under DOS (via DOSXNT) and Windows 3.x, however DOS and Windows 3.x targets
could still be built with future versions (actually, you can use any version of MASM prior to 10, where DOS support was removed).
Quoting the README from the patch directory of an MSDN VC6 SP5/MASM 6.11 bundle CD released in 2001,
Due to changes in the MS-DOS extender used in earlier versions of MASM, MASM 6.14 does not run on Windows 3.1x
or MS-DOS. Either Windows NT or Windows 95 is required to run MASM 6.14. If you are working in MS-DOS or Windows
3.1x, you need to continue using version 6.11d.
Note that you can use MASM 6.14 to develop applications that run under MS-DOS or Windows 3.1x.
According to Microsoft's MASM KB Article Q228454,
"If you need to use MASM on an MS-DOS or Windows 3.1x machine, version 6.11d is the latest version capable of
running under these operating systems."
Updated documentation files were the
README.TXT and
ERRMSG.TXT.
PATCH INFO:
-
DISTRIBUTED AS PATCH (ML611D.EXE / 488k) for versions 6.11 or 6.11a
AFFECTED FILES: ML.EXE, ML.ERR, H2INC.EXE, H2INC.ERR
OFFICIAL DOWNLOAD LOCATION: ftp://ftp.microsoft.com/softlib/mslfiles/
CHANGELIST:
- now supports structure packing on 8 byte boundaries as well as 16 byte
boundaries using the /Zp8 or /Zp16 switches. Older versions of Masm only
allowed up to /Zp4 structure packing.
-
FIXES:
- The opcode generated for the FSETPM instruction has been corrected.
- Errors when using the ALIAS directive and creating COFF object files have been fixed.
- Errors when specifying an entry point with the END directive and creating COFF object files have been fixed.
- Errors when using the ORG directive to back patch the code being generated in a COFF object file have been fixed.
- The extra byte in the listing file for instructions using 32-bit addressing modes has been removed.
- Unresolved externals that could occur when a symbol appeared more than once in EXTERNDEF directives have been fixed.
- You can now step through code in include files when building COFF object files.
- Various Access Violations when generating COFF object files have been fixed.
WHAT OTHERS HAVE SAID:
NOTE TO THOSE BUILDING DOS APPS:
-
Latest Free DOS Linker:
If you use this version or any future version up to MASM 9.0 to assemble 16-bit/DOS code,
you can't use any of the 32-bit linkers released with Visual Studio. Your choices are to
use the 16-bit linker that came with the last full distribution of MASM in version 6.11 (LINK.EXE 5.31.009 dated 7/13/1992)
or the last 16-bit linker released by Microsoft with many fixes (ver=5.60.339 size=364544 date=12/5/1994 file_date=1/13/1995 md5=ed1ff59f1415af8d64daee5cdbd6c12b)
which Microsoft provided as a free download:
The self-extracting Lnk563.exe file provides the following 3 files: CVPACK.EXE, LINK.EXE and README.TXT.
The original download URL was: http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe
-
Latest Free DOS Debugger:
If you want to debug 16-bit programs, you might also want the last release version of CodeView (version 4.10.1,
dated 9/16/1994) to replace the one that came with MASM 6.11. CodeView 4.10
fixed some bugs debugging .COM files, stepping through code using 32-bit registers, etc.
The self-extracting cv41patch.exe file provides 20 files to be
copied into your MASM 6.11 BIN directory (or you may simply run the included CV.EXE standalone).
The original download URL was: http://www.nuvisionmiami.com/books/asm/cv/cv41patch.exe
ML.EXE | 366,080 bytes (358k) | md5=fdc7bc15286109f773e6895c7a2f8e96 | date=8/27/1997 3:49pm | | (Date from Patch File) | |
|
@Version reports: 612
This version of MASM added MMX and Pentium Pro (i686) support and no longer ran under DOS or Windows 3.1.
This was the first version of MASM to require Windows 95.
The MMX line of Pentium processors and the Pentium Pro processors were released by Intel on 10/22/1996 and
11/1/1995 respectively.
Running under Windows 95 or NT 3.1 was now required
as this was the first version of MASM to run exclusively under Win32.
As a direct consequence, Phar Lap's DOS extender no longer needed, thus ML.EXE shrank.
The only changed documentation from prior versions was the
README.TXT.
SYSTEM REQUIREMENTS:
- Personal computer using a 386 or higher processor running Windows 95,
or Windows NT version 3.1 or later.
- 4 MB of available memory.
- Hard disk with 10 MB available space.
- One 3.5" high-density (1.44 MB) disk drive (3.5" low-density (720K)
or 5.25" high-density (1.2 MB) disks available separately with
coupon enclosed).
-
To target Windows 3.1, you need one of the following:
- Microsoft Windows Software Development Kit (SDK) 3.1.
- Microsoft Visual C++ Development System, Standard or Professional Edition.
-
To target Windows NT, you need one of the following:
- Microsoft Windows NT Software Development Kit (SDK).
- Microsoft Visual C++ Development System, 32-Bit Edition.
PATCH INFO:
-
DISTRIBUTED AS PATCH (ML612.EXE / 670k) for versions 6.11, 6.11a, or 6.11d.
AFFECTED FILES: ML.EXE, ML.ERR, H2INC.EXE, H2INC.ERR
OFFICIAL DOWNLOAD LOCATION: ftp://ftp.microsoft.com/softlib/mslfiles/
CHANGELIST:
-
New Pentium Pro Directives:
- .686 - enables assembly of non-privileged instructions
- .686P - enables privileged instructions in addition to the non-privileged instructions
-
MMX Support:
The .MMX directive enables assembly of MMX instructions.
Users can check to see that @Version is 612 or higher to tell if the version
of MASM being used supports the .MMX directive and MMX instructions.
-
FIXES:
- Various Access Violations when generating CodeView debug information (/Zi)
have been fixed.
- Errors when specifying an entry point with the END directive and creating
COFF object files have been fixed.
- Various structure packing inconsistencies when compared to the Microsoft
C/C++ compilers have been corrected. MASM 6.12 should now pack structures the
same as the Microsoft C/C++ compiler when using the same packing options.
-
IMPLIED FIXES? (Removed from Known Assembler Bugs present in
README.TXT for version 6.11d):
- Exiting from MS-DOS Critical Errors - MS-DOS critical errors, such as
attempting to assemble a file on a drive which does not exist or is empty,
produce the "Abort, Retry or Fail?" error message. Selecting "Abort" when
running MASM in MS-DOS may cause memory to be corrupted. This problem does
not occur when running MASM in Windows. To avoid this problem, select
"Retry" or "Fail", as appropriate.
WHAT OTHERS HAVE SAID:
- Intel added Streaming SIMD support to this version in the form of macros (which also supported MMX)
REFERENCE: r_harvey
ML.EXE | 351,744 bytes (344k) | md5=2c6183857c6b692fa75d3967b875e4f9 | date=12/5/1997 1:43pm | | (Date from Patch File) | |
|
@Version reports: 613
The only official change in this version of MASM was the addition of the 3DNow! Technology support, a SIMD
extension to the x86 instruction set released by AMD (Advanced Micro Devices) on 4/28/1998 (initially in the AMD K6-2
processor). However, there were some unofficial changes too.
The only changed documentation from prior versions was the
README.TXT.
PATCH INFO:
-
DISTRIBUTED AS PATCH (ML613.EXE / 815k) for versions 6.11, 6.11a, or 6.11d.
AFFECTED FILES: ML.EXE, ML.ERR, H2INC.EXE, H2INC.ERR, WIN.INC
OFFICIAL DOWNLOAD LOCATION: ftp://ftp.microsoft.com/softlib/mslfiles/
CHANGELIST:
-
AMD 3DNow! Technology Support:
The .K3D directive enables assembly of K3D instructions. Users can check to see that @Version is 613 or
higher to tell if the version of MASM being used supports the .K3D directive and K3D instructions.
-
WIN.INC Updated:
The WIN.INC has changed for the first (and last)
time since the initial version in 6.1. This version makes a change (fix) to line #2405
which is to prefix the SWORD symbol mm so it now reads _mm. I suspect they made this
change to avoid name clashing with the new MMX register set MM0 thru MM7.
UNOFFICIAL CHANGES:
-
Addition of @comp.id symbol to resulting OBJ files:
For consistency with new Visual C++ compiler features at the time, the @comp.id (compiler id) COFF symbol was added to
MASM-created OBJ files starting with this version. This symbol embeds the MASM build number.
The Microsoft linker then picks this value up to encode the undocumented "Rich" header in the final executable module.
WHAT OTHERS HAVE SAID:
ML.EXE | 372,736 bytes (364k) | md5=b54b173761ac671cea635672e214a8de | date=4/12/1999 3:05pm | | (Date from Patch File) | |
|
@Version reports: 614
This version of MASM no longer ran under Windows NT 3.1, but now required Windows NT
3.51, Windows 95, Windows 98 or Windows ME. This version additionally included SSE support, partial SSE2 support and had one fix,
as can be read in the
README.TXT.
This was the officially supported version of MASM for Windows ME as it was bundled with both the XP (2600) and XP SP1 (2600.1106) DDK's;
installed to the "bin\win_me\bin" directory.
SYSTEM REQUIREMENTS:
- Personal computer using a 386 or higher processor running Windows 95, Windows 98,
or Windows NT version 3.51 or later.
- 4 MB of available memory.
- Hard disk with 10 MB available space.
- One 3.5" high-density (1.44 MB) disk drive (3.5" low-density (720K)
or 5.25" high-density (1.2 MB) disks available separately with
coupon enclosed).
-
To target Windows 3.1, you need one of the following:
- Microsoft Windows Software Development Kit (SDK) 3.1.
- Microsoft Visual C++ Development System, Standard or Professional Edition.
-
To target Windows NT, you need one of the following:
- Microsoft Windows NT Software Development Kit (SDK).
- Microsoft Visual C++ Development System, 32-Bit Edition.
PATCH INFO:
-
DISTRIBUTED AS PATCH (Ml614.exe / 858k) for versions 6.11, 6.11a, or 6.11d.
(see MASM KB Article Q228454)
AFFECTED FILES: ML.EXE, ML.ERR, H2INC.EXE, H2INC.ERR, WIN.INC
OFFICIAL DOWNLOAD LOCATION: ftp://ftp.microsoft.com/softlib/mslfiles/
CHANGELIST:
-
Support for SSE (Streaming SIMD [Single Instruction, Multiple Data] Extension) instructions and partial support for SSE2:
- Added support for SSE instructions formerly known as KNI (Katmai New Instructions).
SSE was introduced by Intel in 1999 for their Pentium III series processors shortly after the
appearance of AMD's 3DNow!.
- Added .XMM directive. This is required to assemble the new SSE and SSE2 instructions.
Users can check to see that @Version is 614 or higher to determine SSE support.
- Added partial support for some SSE2 instructions (remaining set completed in version 6.15):
-
MOVQ
PACKSSDW PACKSSWB PACKUSWB PADDB PADDD PADDSB PADDSW PADDUSB PADDUSW PADDW
PAND PANDN PCMPEQB PCMPEQD PCMPEQW PCMPGTB PCMPGTD PCMPGTW PMADDWD PMOVMSKB
PMULHW PMULLW POR PSLLD PSLLQ PSLLW PSRAD PSRAW PSRLD PSRLQ
PSRLW PSUBB PSUBD PSUBSB PSUBSW PSUBUSB PSUBUSW PSUBW PUNPCKHBW PUNPCKHDQ
*PUNPCKHQDQ PUNPCKHWD PUNPCKLBW PUNPCKLDQ PUNPCKLWD PXOR
RCPPS RCPSS
*recognized, but not working until version 6.15
-
FIXES:
- Incorrect A2039 errors indicating 'line too long' have been fixed.
WHAT OTHERS HAVE SAID:
- The OWORD (Octal Word) keyword was introduced replacing MMWORD used in Intel's macros;
"This 16-byte data type is required for SIMD instructions, and should be useful for ad hoc structures."
REFERENCE: r_harvey
MASM 6.15 © 1981-2000 / bundled w/ Visual C++ 6.0 Processor Packs 4, 5 (build 6.15.8803) | [ | Command Line / Help | ] |
ml.exe | 385,072 bytes (376k) | md5=3d52f47ad3a190294323eb80449c9ff6 | date=3/16/2000 3:20pm | | | |
|
@Version reports: 615
This version was bundled with the Visual C++ SP4 and SP5 Processor Packs for Visual C++ 6.0 (an add-on to Visual
C++). Microsoft no longer considered MASM a separate product. Oddly enough, SP6, the last service pack for Visual C++
6.0, actually removes the SP5 the Processor Pack, so you had to hang on to SP5 to keep MASM. Future versions of
MASM would ship directly with the Visual C++ compiler and tools VIA Visual Studio. Microsoft had this to say
for Visual C++ 6.0 SP6:
In addition, the Visual C++ Processor Pack (VCPP) was removed from Service Pack
6. If you have the VCPP installed, installing SP6 will remove it from your
machine. If you wish to continue using the VCPP, you will need to stay with SP5
or migrate to Visual Studio 2002 or 2003 (recommended).
Processor Pack 5 can be downloaded here: vcpp5.exe
Other documentation files installed by Processor Pack 5:
PPreadme.htm (Dec 7, 2000)
procpack.chm (Aug 22, 2000)
MasmRef.Doc (Aug 9, 2000)
Instructions on how to extract MASM from Processor Pack 5 can be found at
The Starman's Realm.
NOTE: I think it is a bug that the word "Beta" is present in the <title> element of the PPReadme.htm file
(see link above). Microsoft removed "Beta" from the title at the top of the page, but they missed the title
that displays in the browser's title bar.
This was the only version of MASM to date with no official changelist but there WERE changes. The Visual C++
6.0 Processor Pack documentation listed the C/C++ Compiler changes but no official word on the MASM changes.
The Processor Pack did contain the handy MasmRef.Doc (see above) you could open in WordPad (write.exe), but no
section explaining the fixes, new features or other changes between versions 6.14 and 6.15.
This version was significant in the fact that it finalized the remaining SSE2 instructions that weren't included
in version 6.14.
SSE2 was introduced by Intel with the initial version of the Pentium 4 in 2000.
Diffing the command line output also indicated that the /omf argument was added.
The MASM executable is now a lowercase filename (ml.exe) and will likely be into the foreseeable
future. The all UPPERCASE filenames of the DOS-days appear to be over :).
CHANGELIST:
- Added command line option: /omf "generate OMF format object file" as the COFF object file format became
the new default for the 32-bit world
- Added the remainder of SSE2 instructions not implemented in version 6.14 (also requires use of .XMM directive):
-
ADDPD ADDSD ANDNPD ANDPD
CLFLUSH CMPPD *CMPSD COMISD
CVTDQ2PD CVTDQ2PS CVTPD2DQ CVTPD2PI CVTPD2PS CVTPI2PD CVTPS2DQ CVTPS2PD
CVTSD2SI CVTSD2SS CVTSI2SD CVTSS2SD CVTTPD2DQ CVTTPD2PI CVTTPS2DQ CVTTSD2SI
DIVPD DIVSD
LFENCE
MASKMOVDQU MAXPD MAXSD MFENCE MINPD MINSD MOVAPD MOVDQ2Q
MOVHPD MOVLPD MOVNTDQ MOVNTI MOVNTPD MOVQ2DQ *MOVSD MOVUPD
MULPD MULSD
ORPD
PADDQ PAUSE PMULUDQ PSHUFD PSHUFHW PSHUFLW PSLLDQ PSRLDQ
PSUBQ PUNPCKLQDQ
SQRTPD SQRTSD SUBPD SUBSD
UCOMISD UNPCKHPD UNPCKLPD
XORPD
*recognized, but not working until version 7.x
REFERENCES:
OSDEV MASM,
German Wikipedia: MASM,
OpenSSL bug list,
MASM32 Blog
MASM 7.0 / bundled w/ Visual C++ .NET 2002 7.0 (any*) & XP 5.1.2600 DDK |
@Version reports: 615
*The version of MASM shipped with Visual C++ .NET 2002 7.0 does not change after SP1 is applied.
This version shipped with the new Visual C++ .NET 2002 7.0 and the Windows XP 5.1.2600 DDK
(located at WINDDK\2600\bin\x86\ml.exe). Another release of
the XP DDK (5.1.2600.1106) bundled an identical ml.exe as the first DDK but was dated 3/25/2002 7:22pm.
Besides cosmetic differences, it appears there were no significant changes. @Version still reports the
previous version of MASM (6.x series).
It is noteworthy that unlike 7.1 and all other later versions of MASM that had matching build numbers with the Visual Studio
toolset shipped with, the Visual Studio .NET 7.0 BETA 1 released a unique MASM that not only reported 615 for @Version, but
also reported 6.15 on the command line! It is likely Microsoft hadn't finalized the build environment changes needed to
fully integrate it within the Visual Studio toolset at this time.
CHANGELIST:
-
Copyright Year(s) on Command Line:
Starting with version 7 and into the future, Microsoft stopped displaying the copyright years
that used to display on the command line.
-
ML.ERR Dependency Removed:
The ML.ERR companion file required for MASM to run was present in almost the entire 6.x line (except
version 6.1a), but
starting with version 7 and into the future, the error message display strings ml.exe
read from this file were moved into ml.exe itself.
Additionally, the newly embedded error message strings are now UNICODE for localization purposes.
NOTE: the ml.exe version released with the XP 5.1.2600 DDK did come with an ml.err file that was
identical to the ml.err released with version 6.15 (different date though). This was a bug as it
was confirmed the ml.exe assembles without it. Version 6.15 will NOT even attempt assemble without this file
present.
-
MASM retrofitted with a version resource block:
Although MASM has been 32-bit for 4 years, its never had a version resource block until now
(view it by clicking the build-version link above). There is one exception: MASM386 had a version resource block,
but it would be considered non-standard and obsolete compared to the rest of Microsoft's Win32 binaries.
All future versions of MASM will contain a version resource block as well.
WHAT OTHERS HAVE SAID:
- Buffer and stack overflow checking, warnings
REFERENCE: r_harvey
@Version reports: 710
In addition to being primarily released with Visual Studio .NET 2003 7.1, this version of MASM was also bundled
with the Windows Server 2003 SP1 DDK 3790.18030 located in "WINDDK\3790.1830\bin\x86".
CHANGELIST:
-
SAFESEH Support:
The .SAFESEH directive and /safeseh option were added.
.SAFESEH identifier
Registers a function as a structured exception handler. identifier must be the ID for a locally defined
PROC or EXTRN PROC. A LABEL is not allowed. The .SAFESEH directive requires the /safeseh ml.exe
command-line option. The command-line option is described on the command line as:
Marks the object as either containing no exception handlers or containing exception handlers that are all declared with .SAFESEH.
Page 345 of the book
Practical Malware Analysis
sheds some light on SafeSEH:
The ExceptionHandler function will be called first whenever an exception occurs. This action will be
subject to the constraints imposed by Microsoft's Software Data Execution Prevention (Software DEP,
also known as SafeSEH). Software DEP is a security feature that prevents the addition of
third-party exception handlers at runtime. For purposes of handwritten assembly code, there are several
ways to work around this technology, such as using an assembler that has support for SafeSEH
directives. Using Microsoft's C compilers, an author can add /SAFESEH:NO to the linker command
line to disable this.
- Unlike MASM 7.0, @Version correctly reports a version matching the build number; in this case, 710
@Version reports: 800
Visual Studio 2005 offered something that had never been available before: the Express Edition. This edition contained a
fully functional although limited integrated development environment with compilers and tools for
educational/trial purposes, available for download, completely free (with licensing restrictions of course).
These tools included the Win32 version of MASM 8, although it had to be downloaded separately
( MASMsetup.EXE
released June 7th, 2006) from Microsoft's website exclusively for the Express Edition. This version was the first version of MASM that was offered by Microsoft
completely for free.
The Express Edition also marked the first time Microsoft's C# compiler was offered for free. The C/C++ compiler
was first offered for free in the stand-alone download bundle: “Visual C++ Toolkit 2003” (VCToolkitSetup.exe) in the previous
release of Visual C++ (i.e. 7.1). This included only a C/C++ compiler, linker and some libs/includes, but nothing else.
That Toolkit was superseded by the Express and Community Editions that would follow, providing access to a full blown IDE and tools.
This version also marked the debut public release of the Win64 MASM (ml64.exe) for the amd64 architecture (a.k.a. x64, x86-64, EM64T, Intel 64)
which shipped with the Professional and Academic versions of Visual Studio.
Only the Win32 version would be offered for free and this was only through the MASMsetup.EXE (add-on) package. As an alternative, the feature-complete BETA 64-bit tools (including the 64-bit assemblers and compilers) are
still freely available from
Microsoft's Visual Studio 2005 BETA REFRESH package. As with MASMsetup.EXE,
you can extract the files contained within these setup files (as well as the nested setup files) using a typical archive extractor program such as WinRAR and 7Zip.
With the advent of the new 64-bit MASM, Microsoft includes both 64 and 32 bit variations (PE32+, and PE32 respectively) allowing 64-bit assembly to be performed
on 32-bit or 64-bit versions of Windows.
As a side-note, the versions of MASM offered in the free editions (Express/Community) are identical to the versions
present in the retail editions. The only difference are the licensing restrictions and file timestamps.
This was the first version of 32-bit MASM to have a dependency on anything other than kernel32.dll (with
exception of NTDLL.DLL in versions 6.1 and 6.1a about 13 years prior)! MASM was now dependent on the Visual C
runtime library MSVCR80.DLL and ADVAPI32.DLL. In credit to Microsoft, they did trim the executable size from
404k in version 7 to 342k in version 8 freeing up 62k. The executable actually became smaller than every version
of MASM released after 6.00B
(14 years prior) which was 244k! Until version 8, Microsoft must have been statically linking to the C runtime
library and possibly others. Problem now is, MSVCR80.DLL is 621k, so you have to haul this thing around with MASM 8
unless you also want to have the whole Visual Studio 2005 8.0 installed. This isn't
considered to be a problem by most because not only is disk space cheap nowadays, but if you want to link your
object code, you are going to need the linker (link.exe). And, the linker has been dependent on various runtime DLLs since
version 6.15 so we might as well get used to the bloat. :)
CHANGELIST:
- MASM expressions are now 64-bit values. In previous versions MASM expressions were 32-bit values.
- SSE3 instructions support (a.k.a PNI, Prescott New Instructions) introduced by Intel on 2/1/2004:
- The instruction __asm int 3 now causes a function to be compiled to native. For more information, see __asm.
- the following are now documented: ALIAS (MASM) and .FPO
- operators added: IMAGEREL, HIGH32, LOW32, and SECTIONREL
- added .686 (Intel and AMD variant) call-gate instructions:
- SYSENTER
- SYSEXIT (requires .686P)
- SYSCALL
- SYSRET (requires .686P)
- directives added:
- MMWORD (64-bit data type for MMX)
- XMMWORD (128-bit data type for SSE)
- SQWORD (signed QWORD / 8 signed-bytes / version undocumented)
- The SEGMENT directive now supports additional attributes.
-
Changes to Command Line Options:
- /omf now implies /c
- ml.exe does not support linking OMF format objects
- /errorReport "Report internal assembler errors to Microsoft" option added to ml.exe and ml64.exe
-
/Sc "Generate timings in listing" no longer supported. Microsoft either must no longer think
people are or should be concerned with the clock-ticks of each instruction, or it may be
too difficult to maintain
the timings of each instruction on the various different types of processors. It may also not be
possible to get exact timings with the newer processors.
The official documentation between 7.1 and 8.0 no longer list this option:
- /Sg (asm code in listing) (the option still works, but appears to be synonymous with /Sa)
This docs also say:
- /w now implies /W0 and /WX instead of just /W0
This option has been added to the docs (although was present in 7.1 command line):
- /X (ignore INCLUDE environment variable)
- H2INC.exe will not ship in Visual C++ 2005. If you still need it, use from a previous version.
-
Introduction of the 64-bit Assembler (ml64.exe):
ml64 is a version of MASM for the x64 architecture. It assembles x64 .asm files into x64
object files. Inline assembly language is not supported in the x64 compiler. Additionally, the
following command line arguments available for the 16/32 bit version are not available for
ml64:
- /AT (tiny model)
- /coff (common object file format)
- /omf (object module file format)
- /Cu (uppercase identifiers)
- /FPi (floating-point emulator fixups)
- /Gc (FORTRAN or Pascal calling convention)
- /Gd (C-style calling convention)
- /GZ (stdcall calling convention)
- /H (external name significant characters)
- /safeseh (no exception handlers or all handlers .SAFESEH.)
- /Zm (M510 compatibility)
The following MASM directives have been added for ml64 (x64):
- .ALLOCSTACK
- .ENDPROLOG
- .PUSHFRAME
- .PUSHREG
- .SAVEREG
- .SAVEXMM128
- .SETFRAME
- PROC (updated with x64-only syntax)
WHAT OTHERS HAVE SAID:
-
Support for the SSE3 Instruction Set:
REFERENCE: Intel article: Streaming Simd Extensions 3 / VS.NET 2003
REFERENCE: pcdosretro
-
Fast compile times, stricter type checking, separate 32-bit and 64-bit assemblers, the 64-bit lacking many of the features:
"One of the great things about MASM 8.0 (other than faster compile times) is the stricter
type checking."
"Probably the most disappointing part of MASM 8 is that Microsoft decided to split the
assembler: one for 32-bit and one for 64-bit. And the 64-bit version is missing a lot of the
polish of its older brother. It doesn't support many of the higher level constructs or
calling conventions. So no .IF, .WHILE or automatic declaration of function parameters. Minor
nits include no support for C++ function name decoration and no support for register-based
calling conventions (such as __fastcall). These just make it trickier when you have to
integrate 32-bit and 64-bit assembly code with C & C++."
REFERENCE: Phoenix Technologies 2006 Blogs
- Various opinions are that MASM 8 broke code that used to work with previous versions:
"I tried ML.exe & Link.exe from latest VisualStudio 2005, but it sucks
Linker 8.0 do not support some command line switches, assembler fails sometimes with good
(assembled ok by all prev. version) code"
"I agree ML.EXE 8.00 from Visual Studio 2005 is not so good."
REFERENCE: Winasm Forums
- BUGS FIXED in v8: REFERENCE: JWasm Manual
- "TYPE xmm0" will return 10 in Masm v6 and v7 - the correct value is 16.
- for Masm v6 and v7, if an array > 64 kB is defined and output format OMF is selected, the
array's size will be mod 0x10000 only.
- silent truncation of immediate constants: Masm v6 and v7 will accept line "mov
[word_variable],12345h" without error.
- If a section contains more than 0xffff relocations in COFF, the number of relocations that is
stored in the object module is just the value of the lower 16-bit half of the relocation
count.
@Version reports: 900
*The version of MASM shipped with the Express Edition is identical to that in the retail editions; the Express Edition required Service Pack 1 to obtain
MASM. It was also distributed with the Windows Driver Kit (WDK) 7.1.0.
This was the last full-featured version of MASM to support legacy 16-bit DOS code and processors in the 80x86 family prior to the 386.
MASM 10 has removed this support. This was the first version of MASM to require Windows 2000 as opposed to Windows 95 which has been
required by all prior versions since 6.12.
The changelist below is based on MSDN information found from
VS2008 Compiler
Intrinsics. The C/C++ compiler documented support for the new intrinsics reflected in MASM's newly supported
instruction sets, but not a word on MASM's changes.
CHANGELIST:
-
New Instruction Set Support:
- SSSE3 (Supplemental Streaming SIMD Extensions 3) released by Intel on 6/26/2006
- SSE4.1, SSE4.2, SSE4A (Streaming SIMD Extensions 4, a.k.a. “HD Boost”) released by Intel on 9/27/2006
- AES (Advanced Encryption Standard New Instructions or AES-NI) proposed by Intel in March of 2008
WHAT OTHERS HAVE SAID:
-
JWasm Manual: Bugs FIXED in v9:
- the infamous "invoke" bug: if an argument for invoke has to be expanded (from BYTE or WORD to
DWORD, for example ), bad code was generated.
REFERENCE: JWasm Manual
-
Outstanding Bugs:
- Wildcard support (*.asm) broken since 8.0
REFERENCE: MASM Forums
-
You can pass more arguments to a macro than needed:
include \masm32\include\masm32rt.inc
MBox MACRO text:REQ, title:REQ, style:REQ ; 3 arguments received
invoke MessageBox, 0, text, title, style
ENDM
.code
MyTitle db "Ciao", 0
start:
MBox 0, chr$("Message text, not title!"), addr MyTitle, MB_OK ; 4 arguments passed
exit
end start
REFERENCE: MASM Forums
-
Assembly gets slow, and ML may eventually freeze, for large buffers in the .data? section:
.data?
MySlowBuffer db 600000 dup(?) ; 0.6 mega: about 5 seconds
The workaround is a macro using the ORG directive (I owe this idea to drizz and MichaelW):
include \masm32\include\masm32rt.inc
mkbuf MACRO var, BufLen
LOCAL lbl
.data?
align 4
lbl LABEL byte
ORG $+BufLen-1
db ?
.data
var dd lbl ;; define it in the data section
.code
ENDM
.data?
; MySlowBuffer db 600000 dup(?) ; 0.6 mega: about 5 seconds
.code
start: mkbuf MyBuffer, 100000000 ; one-hundred mega
invoke MessageBox, 0, chr$("Done!"), chr$("Fat buffer:"), MB_OK
exit
end start
REFERENCE: MASM Forums
-
The offset problem: Both versions of this code work for ml 6.14 and JWasm but ml 9.0 says
"error A2070:invalid instruction operands"
.data
MyAccels ACCEL <FCONTROL or FVIRTKEY, VK_S, IdMenuSave>
LastAccel ACCEL <FVIRTKEY, VK_ESCAPE, IdEscape>
...
.code
invoke CreateAcceleratorTable, addr MyAccels,
1+(offset LastAccel-MyAccels)/SIZEOF ACCEL
invoke CreateAcceleratorTable, addr MyAccels,
1+(dword ptr LastAccel-dword ptr MyAccels)/(SIZEOF ACCEL)
No workaround found yet, except sacrificing a register...
REFERENCE: MASM Forums
-
JWasm Manual: Bugs STILL PRESENT as of v9 (possibly fixed in future versions):
Many of these bugs are old enough that they have likely become “features”, courtesy of Microsoft.
It is not know which exact version of MASM introduced each bug, but many were present from MASM's
“gold standard” versions 6.14 and 6.15, likely contributing to the reasons not to fix them.
Although possible some or all might never be fixed, it is possible some may have been fixed in v10 and/or greater.
The bug list below was copied from JWAsm's documentation (the closest clone to MASM available, and free),
but JWAsm has fixed them all as of v2.11a (Released Nov 16th, 2013)!
- PROTOs contained twice in the source caused an EXTDEF entry to be generated in the object module.
- a nested structure might cause a GPF in Masm if the embedded STRUCT's starting offset has to
be adjusted due to alignment.
- defining huge arrays in Masm is very slow and might even cause a deadlock if COFF has been
selected as output format.
- Masm doesn't flag invalid numbers in struct/array initializer strings.
- if an ALIAS is defined somewhere in the source and the symbol table is listed, a 'General
Failure' error occurs in Masm if output format is OMF.
- Type "coerces" for DWORD data items defined in a 32bit segment are ignored by Masm, i.e., "dd
far16 ptr <symbol>" will generate a near32 fixup instead of a far16 one.
- if the ALIGN directive has to add 5 bytes in 32bit code segments, Masm includes an "add
eax,0" opcode, which isn't a no-op because flags are modified.
- preprocessed output with option -EP may erroneously contain text macros and macro function
calls if the macros are located in the initialization string of a structured variable.
- Masm generates wrong code if a conditional jump is coupled with a type coercion which
modifies offset magnitude. Examples: "jz near32 ptr ..." in 16bit code or "jz near16 ptr ..."
in 32bit code).
- if the arguments given to Masm end with an option which expects a parameter (i.e. "ml -c
-Fo"), a 'General Failure' may occur.
- floating-point data items in Masm can be followed by any suffix (example: REAL4 1.0foo,
2.0bar). JWasm won't accept this.
- If a local is defined inside a macro, Masm will create a unique name for it. The name is
constructed by using '??' as prefix, followed by a hexadecimal number with 4 digits. There is
no check for overflow, however, so if the total of locals in all macros exceeds 65536,
strange errors will occur.
- If a weak external is defined for -coff with the ALIAS directive, an invalid fixup - and also
a strange entry in the module's symbol table - is created.
- If a symbolic constant (=equate) is made public in OMF format, Masm will store the symbol's
value in a 16-bit record if it is in the range -32768 ... 65535. If the symbol is referenced
in another module as a 32-bit number, it is always zero-extended, never sign-extended; hence
values -1 ... -32768 will become 65535 ... 32768.
- if data labels become public by the -Zf option ( and not by the PUBLIC directive ), their
names are not decorated. Also, if format is COFF, they won't become true publics, they're
just included in the symbol table with class "static".
REFERENCE: JWasm Manual
MASM 10.0 / bundled w/ Visual C++ 2010 10.0 from VS 2010 10.0 (any*) | [ | Command Line Help | ] |
@Version reports: 1000
Visual Studio 10.0 Express released 32-bit executable versions (PE32) of both ml.exe and ml64.exe assemblers, the same
that were released in the retail editions except with different timestamps. The Express Edition did not release the 64-bit ml64.exe.
There were slight differences in the binary executable between the initial
release version and SP1. These differences are most likely the build number
changes in the version resource block, but no functionality changes.
Version 10.0, appearing 29 years after its initial version in 1981, has made one of the most significant changes in
MASM history. All support for 16-bit/DOS assembly and any processor support prior to the 386's 32-bit modes is
now gone. This was also the first version of MASM to require a minimum of Windows XP.
CHANGELIST:
- Support for the AVX Instruction Set (Advanced Vector Extensions) (proposed by Intel in March of 2008)
- Support for YMMx registers; i.e. ymm0-ymm8 for x86
-
The addition of the YMMWORD data type supports the 256-bit multimedia operands that are
included in the Intel Advanced Vector Extensions (AVX) instructions.
-
Several directives were removed from the Microsoft Macro Assembler Reference compiler. The
removed directives are .186, .286, .286P, .287, .8086, .8087, and .NO87.
-
ML.exe has removed the following command line options (although Microsoft did not update their
help):
- /AT "Enable tiny model (.COM file)"
- /FPi "Generate 80x87 emulator encoding"
- /H "Set max external name length"
WHAT OTHERS HAVE SAID:
MASM 11.0 / bundled w/ Visual Studio Express 11.0 (2012) |
@Version reports: 1100
This was the first version of MASM (and all of the Visual Studio toolset) to require a minimum OS of Windows Vista.
This change was made to the PE header.
Aside from that, no official changelist was released and a diff of the MSDN documentation also revealed no changes.
MASM 12.0 / bundled w/ Visual Studio 12.0 (2013) |
@Version reports: 1200
The Visual Studio 12.0 (2013) toolset (including this version of MASM) was marked with the debut release of
the Community Edition: a free version of Visual Studio for individuals, academia, open source projects and small
businesses that is
functionally equivalent to the professional edition minus CodeLens and Team Foundation Server features.
Microsoft oddly continued to release the free and crippled Express Edition. Both the Community and Express editions of
Visual Studio included MASM.
Unfortunately, no official changelist was released and a diff of the MSDN documentation also revealed no changes.
MASM 14.0 / bundled w/ Visual Studio 14.0 (2015) |
@Version reports: 1400
This should have been MASM 13.0, but the entire Visual Studio toolset skipped the "unlucky" number in favor of 14.0.
If Microsoft got flack from the superstitious for shipping Visual Studio 2013 two years prior, they certainly didn't make the same mistake twice!
The Visual Studio 14.0 (2015) C Runtime dependency DLL was restructured in this version, affecting most of the tools including MASM.
What would have been MSVCR140.DLL is now broken into VCRUNTIME140.DLL and various "api-ms-win-crt-CCC-VVV" DLLs,
where CCC is the category and VVV is the version.
As with the prior two major versions of MASM, no official changelist was released for this version and a diff of the MSDN documentation revealed no changes.
A side note that may be of interest are some new dependencies taken on by the Microsoft linker (at least for test building the most minimal assembly applications):
- Both the x86 and x64 linkers now require the Microsoft C++ Runtime (MSVCP140.DLL)
- When linking a minimal x64 module, the linker now requires MSPDBCORE.DLL, whether or not a PDB is generated
MASM 14.1 / bundled w/ Visual Studio 14.1 (2017) |
@Version reports: 1410
The next edition of the Visual Studio toolset (2017) initially began with version 14.1, but as
of late 2017, are in the 15.x range due to the
changes
Microsoft has made to its build versioning method.
In other words, a concrete version number is no longer tied to the release year starting in 2017.
At this point, the entire Visual Studio toolset is so large,
Microsoft stopped releasing .ISO installer DVD images. Everyone is now forced to use
their web downloader to fetch the individual components you want. The toolsets that include MASM
(as well as the other associated Visual C++ tools) are present in any of the following components:
- Microsoft.VisualStudio.Product.BuildTools (Visual Studio Build Tools)
- Microsoft.VisualStudio.Workload.NativeMobile (Mobile development with C++)
- Microsoft.VisualStudio.Workload.NativeDesktop (Desktop development with C++)
As with many of the prior versions of MASM, there have been no documented changes.
2020-08-29 * added unofficial fixes section for notorious "PUSH-immediate" bug (and magazine article links) for version 4.0
* refactored summary and added internal README document for version 5.NT.02 (i.e. masm386)
2020-08-24 * added PCMPGTx instructions to SSE2 list for version 6.14
* added SSE3 instructions list for version 8.x
* added support for YMMx registers for version 10.x
2020-08-19 * historical corrections and overhaul of SSE and SSE2 support (with instructions list) for versions 6.14 and 6.15
2018-08-21 * Added 2 MASM versions for VS.NET 7.0 and updated summary: BETA1 6.15.9030, BETA2 7.00.9254
2018-03-02 * Added MASM variant QuickAssembler section (all known versions) between MASM 5.10B and MASM386
2018-02-28 * [this] changelist moved to bottom of the page
* summary revisions
* version 1.0 IBM: added links to Chrisophe Lenclud's blog entries (including
"Debugging IBM MACRO Assembler Version 1.00") where MASM's hang/out-of-memory
bug was found and fixed; encountered when running under some environments.
2018-01-02 * version 6.11a - removed unofficial ML611A.ZIP archive (from EMS Professional's "ASM UTIL"
shareware collection CD) and replaced with original download archive: ML611A.EXE
(the file contents were identical)
2017-11-22 * inserted opening paragraph describing MASM at the very top of page; cleaned up references for
Itanium, for which a version of MASM might never have existed.
* version 14.0: added 3 version (VS 2015) 14.0.24218.2 binaries bundled with VS 14.1 (2017)
modified summary to include new linker dependency side-note
* version 14.1: added 3 version 14.10.25019.0 binaries from VS 14.1 (2017) and summary
2017-11-16 * version 8.0: added PE32/64 versions for build 8.00.50727.762 that shipped with SP1 pro & academic editions;
minor summary revision
2017-07-18 * version 12.0: added blurb about the Visual Studio Community Edition debut for Visual Studio 2013
2017-07-14 * version 8.x added Intel/AMD .686 call-gate instructions
2017-07-09 * added versions 11.0, 12.0 and 14.0
2017-04-20 * added info for one of the earliest known MASM386 5.NT.02 variants from an MSDN Win32 DDK
CD for NT 3.1 Build 1.239.1; also incorporated it into the summary
2017-04-05 * version 7.1: quoted "Practical Malware Analysis" book for more SafeSEH details
2017-04-04 * added "Detect It Easy" results for versions 1.0 IBM, 1.0, 1.06, 1.10, 1.25, 2.04, and 4.0
(built using IBM PC Pascal, possibly assembler and Microsoft C)
2017-03-21 * updated version 6.14 to include that it was additionally bundled with first two XP DDK's for Windows ME
* updated version 6.11d to include that it was also the last version (in addition to MS-DOS)
that would run under Windows 3.x and quoted a readme from an MSDN VC6 SP5/MASM bundle CD
2017-03-02 * added MASM386.EXE build 3.50.794.1 (newer) that shipped with the Win32 SDK for NT 3.5 and reworked summary
2017-02-08 * added unofficial change to MASM 6.13; addition of @comp.id COFF symbol to OBJ files for consistency with other
Visual C++ tools to support Microsoft's undocumented "Rich" header.
2017-01-02 * updated version 9.0 to include that it was distributed with the WDK 7.1.0
2016-11-03 * MASM 9 summary edited to include that SP1 is required to obtain MASM when using the Express Edition
2016-11-02 * added first batch of 64-bit assembler info for versions 8, 9 and 10
* edited summaries for version 8 (incl. official BETA REFRESH package link), and 10 mostly for 64-bit assembler support
* added minimum OS required for versions 6.12, 9 and 10
2016-11-01 * added OS/2 versions of ML.EXE to 6.0 and 6.00B
* designated DOS/Dual Mode executables for 5.10A variations
* version 8 summary now emphasizes first public Win64 release for the amd64 architecture (a.k.a. x64, x86-64, EM64T, Intel 64)
2016-10-09 * added dual-mode executable information for version 5.10 and alternate dates for both
* normalized version references from version 5.1 to 5.10
2016-09-29 * added version 1.06
* added "Runs Under" OS column
* removed 12:00am time from associated table and version header timestamps where time was unavailable
* 2.04 changes: added "SEATTLE COMPUTER Utility" disk, updated timestamps and reworded summary
* moved incorrectly placed comment by r_harvey (about MASM386/5.NT.02) from MASM 5.10B to MASM386 5.NT.02 section
* normalized version references; where docs and command-line version string differ, we'll give priority to the command-line string:
-6.0B to 6.00B
-1.1 to 1.10
2016-09-08 * 6.0B changes:
-added README.DOC
-added changelist info from corresponding README.DOC
-added OLDSTDCALL (6.0B) to table of Non-Reserved Operands
-refactored summary to reflect changes above
|
| |
|
|
|