jwasm/History.txt
2014-06-18 19:16:56 +04:00

2103 lines
115 KiB
Plaintext

Changelog
__/__/2014, v2.12:
Bugfixes:
- COMM directive: there was no check that numeric arguments 'size' or
'count' did fit into 32-bits; see comm06.aso.
- regression in v2.10-2.11: in 16-/32-bit, if a FASTCALL procedure was
first prototyped and then defined, the assembly process may have stopped
with error 'General Failure'; see proc9.asm.
- regression in v2.10-2.11, COFF format: if full segment directives were
used and a bss segment didn't have the expected class name, jwasm may
have calculated wrong file positions of section data and relocations;
see coff1.asc.
- operator OPATTR: bit 1 (=indirect memref) and language type flags of
result may have been set even if operand was an invalid reference; see
opattr9.asm.
- ELF format: object module may have been larger than necessary due to
bss section sizes that were not ignored for file offset calculations.
- GPF might have occured if a TYPE for an undefined variable was
specified in an expression; see expr5.aso.
Other changes:
- OPTION WIN64:4 added.
11/16/2013, v2.11a:
Bugfixes:
- regression in v2.11, Unix version only: _splitpath() emulation code
didn't handle correctly dots in directory part of the filename.
10/20/2013, v2.11:
Bugfixes:
- regression in v2.10: type expression may have given incorrect result
if it contained an indirect memory operand; see types14.asm.
- shift instructions with unsized memory operand as first operand were
silently assumed to have byte size; see shift4.aso.
- concatenation operator (a '\' as last non-white space character) wasn't
handled if it appeared after line expansion only; see expans38.asm.
- EXPORT or PRIVATE attributes in a PROTO directive weren't ignored;
this may have caused problems if the attribvtes differed from those in
the corresponding PROC directive.
- userdefined prologue/epilogue macros: bit 7 of flag argument (=export)
wasn't set.
- 64-bit: if OPTION FRAME:AUTO was set, the default prologue of all PROCs
with FRAME attribute did setup the RBP register, even if no params or
locals were defined.
- in v2.00-2.10, CMP instruction did not reject the LOCK prefix.
- 64-bit, CodeView debugging info: stack variables were defined via
S_BPREL32-records, which works only as long as value of RBP fits in
32-bit; changed to S_REGREL32.
- INVOKE directive: signed 16-bit arguments were zero extended if the
target's parameter was of VARARG type; see invoke24.asm.
- INVOKE directive: in 16-bit code, extending arguments to DWORD size
didn't always work correctly; see invoke25.asm & invoke26.asm.
- undefined members in critical expressions were accepted in some cases;
see struct39.aso.
- 64-bit: if more than 128 unwind codes were created inside a FRAME
procedure, a GPF may have occured.
- 64-bit: unwind codes generated by .ALLOCSTACK weren't always correct.
- 64-bit: codeview line number info was not quite correct for first line
in FRAME procs; consequently, there may have been a delay of one line
until the debugger was able to show the contents of stack variables.
- codeview debug info for symbols of type FWORD wasn't correct.
- VMOVMSKPD, VMOVMSKPS, VMOVNTDQ, VMOVNTPD, VMOVNTPS didn't accept
256-bit operands.
- INVOKE: if byte-registers AH-DH were used as arguments for a BYTE
parameter in 32-bit, the wrong register was pushed; see invoke28.asm
and invoke29.asm.
- INVOKE: register arguments were always zero-extended, even if there
was a signed type coercion; see invoke31.asm - invoke34.asm.
- INVOKE, 16-bit: "push 0" may have been generated, even if current
cpu was 8086, resulting in an assembly error.
- INVOKE, Win64: default size of integer constants was 8 - changed to 4.
- COFF: if -Zd or -Zi was set and there were multiple code sections
containing code outside of procedures, the assembler may have crashed.
- COFF: relative paths were missing in file entries of symbol table.
- runtime conditionals: constant expressions coupled with && or ||
operator may have created wrong code; see rtcond7.asm - rtcond9.asm.
- VMOVSD and VMOVSS didn't accept memory reference as second argument;
see avx6.asm.
- 64-bit: direct memory addressing with non-RIP-relative addresses didn't
work in all cases; see mov644.asm.
- overflow and underflow of real4 and real8 constants wasn't detected
reliably; see float8.aso.
- empty quoted strings were accepted as instruction operands; see
quotstr2.aso ).
- fatal errors were displayed, but did not appear in the .err-file.
- BSS segments with the COMDAT attribute caused a GPF.
- INVOKE: if the target's offset magnitude wasn't the current one ( i.e.
calling 16-bit procedure from 32-bit code ), the generated code had
problems in some cases; see invoke37.asm & invoke38.asm.
- regression in v2.09-2.10: in 16-bit code, a jump extension may have
occurred although the distance was 'short'; see forward8.asm.
- 64-bit: register names TR3-TR7 were included in reserved words table.
- COMM directive did accept NEAR/FAR types; see comm05.aso.
- OMF format, options -Zd, -Zi: the size of line number records may have
exceeded 1024; see linnum.asc.
- OMF format, option -Cu: names of communals and exports weren't converted
to uppercase; see casemap1.asc.
- ALIGN in 16-bit code segments: the 2-byte filler was different from
Masm's; see align4.asm.
- macro functions calls after directives .IF, .ELSEIF, .WHILE or .UNTIL
confused the tokenizer if one of the macro arguments was a <>-literal;
see expans39.asm.
- a macro placeholder ( argument or local ) may not have been detected if
it was preceeded by a '!'; see expans40.asm.
- jwasmd.exe: no FPU emulation code was included, causing strange errors
when jwasm run on systems without FPU ( 80386/80486SX ) and floating
point initializers were used in the assembly source.
- EXTERN directive, weak externals: an "infinite" loop may have occured;
see extern15.asc.
Other changes:
- OPTION STACKBASE added.
- macro parameter attribute VARARGML added.
- 64-bit, OPTION FRAME:AUTO: better prologue generation if XMM registers
are contained in the PROC's USES clause.
- OPTION RENAMEKEYWORD is now able to rename a keyword temporarily only.
- data labels that become public via cmdline option -Zf will be decorated.
- anonymous members in unions will be added to codeview debug info; they
get a generated name ( which is a number, prefixed by "@@" ) to make
them acceptable to the MS debug engine.
- INVOKE, 64-bit: signed/unsigned integer argument expansion added.
- OMF format: multiple THEADR records are written if line number info
is contained in more than just one source file.
- jwasmd.exe linked with updated hdpmi32 stub ( loadpex.bin ).
- precompiled binaries jwasm.exe and jwasmd.exe now linked with jwlink.
- encoding of FADD, FMUL, FDIV, FDIVR, FSUB and FSUBR with register st
as both first and second operand does now match Masm's encoding.
04/17/2013, v2.10:
Bugfixes:
- option -Zi: the CodeView symbolic debug info did contain type indices
of value 0 - which caused debuggers based on the MS debug engine to emit
a warning.
- a struct definition just after PROC or LOCAL may have triggered
prologue generation, and thus error "statement not allowed inside struct
definition" did appear.
- regression in v2.08-2.09 with option -Zne: a segment register override
may cause error 'invalid use of register'; regression test overrid3.asm.
- regression in v2.08-2.09: a float as operand behind EQU was stored as
a number (value 0), not as text; regression test equate26.asm.
- a forward reference might have caused an error if the reference was once
interpreted as a label and then as a structure name; regression test
struct34.asm.
- regression in v2.09: if the difference of two labels ( at least one must
be a forward reference ) was stored in a byte variable, an error occured
if output format was COFF; regression test data10.asc.
- ALIAS segment attribute: the alias name was likely to become "corrupted".
- operators IMAGEREL and SECTIONREL were ignored if their operand was the
displacement of an indirect memory reference; regression test coffop.asc.
- -pe: size of data directory for imports did comprise all import data.
- -pe: in object table, the entry of the internally generated .reloc
section may have been invalid.
- -pe: the exported names table wasn't sorted in ascending order.
- -coff: weak externals defined via "extern sym (altsym) ..." had
characteristics IMAGE_WEAK_EXTERN_SEARCH_ALIAS instead of
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY.
- ALIAS directive: the alias name in the object module wasn't decorated.
- OMF format: a linker "pass separator" comment record was written in any
case; according to OMF docs it is NOT to be written if a starting
address is present ( Masm also omits the record then ).
- if the third argument of an instruction was a forward reference, error
'invalid instruction operands' was emitted in most cases; regression
test forward4.asm.
- strcpy() was used to copy overlapping strings when a macro was stored -
this may not work with all compilers; replaced by memmove().
- comparison of pointer types ( with or without using TYPE operator ) had
problems; regression test types7.asm.
- option -Fd without filename argument might have caused a GPF.
- if a symbol with local scope was to be defined and the name was
referenced previously ( but not defined [yet]! ), a confusing error msg
"Symbol already defined" was emitted; regression tests local2.aso and
proc5.aso.
- -bin: absolute segments weren't fully supported; regression tests
absseg2.asm and absseg3.asm.
- directives PUSHCONTEXT & POPCONTEXT did not behave exactly as in Masm;
regression test context2.asm.
- -coff: if a section contained more than 0xffff relocations, the count
in the section header was truncated and flag IMAGE_SCN_LNK_NRELOC_OVFL
wasn't set.
- comparison of GPR TYPEs did ignore ASSUME; regression test types8.asm.
- INCLUDE directive: directory part of a relative path may have been
ignored if the current source file wasn't in the current directory.
- -coff: static (=private) PROCedures weren't included into the coff
symbol table.
- it was possible to change the ALIAS segment attribute; regression test
alias2.asc.
- if OPATTR operand was an undefined struct member, an error was emitted;
regression test opattr3.asm.
- if an alias defined via '=' or EQU directives was forward-referenced,
it might have failed to trigger a necessary phase error, resulting
in a premature end of the assembly task; regression test forward5.asm.
- directive ENDP, v2.05-2.09: the matching of the labels ( PROC and
associated ENDP ) was only tested with the length of the PROC label -
which wasn't reliable; regression test proc6.aso.
- option -Zg, INVOKE directive: if an argument was to be extended from
WORD to DWORD, the hiword wasn't initialized to 0; regression test
invoke21.asc.
- type coercion inside brackets wasn't dereferenced for usage outside
the brackets; regression test ptr2.asm.
- regression in v2.05-2.09, options -Fo, -Fl,...: white spaces in filename
argument did confuse the cmdline parser.
- in v2.09, directive REP[EA]T may have triggered error 'too many arguments
in macro call' ( JWASMR.EXE only? ).
- regression in v2.09: if a struct member was an alias for another struct
or union, it was not properly initialized; regression tests struct35.asm
and struct36.aso.
- option -Zf: code labels created via '@@:' weren't sorted out.
- regression in v2.05-2.09: code label @@: at the very beginning caused
problems ("symbol not defined" ).
- regression in v2.07-2.09: if the member part in a "dot"-expression was
enclosed in (), it wasn't accepted; regression test dotop5.asm.
- regression in v2.08-2.09: variable type was overwritten by assumed type;
regression test assume10.asm.
- if a text macro expanded to a preprocessor directive and wasn't the
first token in a line, the result might have been "unexpected";
regression test equate27.asm.
- LODS[B|W|D|Q]: if optional operand contained a DS override, a DS prefix
byte was generated; regression test string3.asm.
- INVOKE may have rejected a valid argument if it was a struct type with
size 4,6 or 8; regression test invoke22.asm.
- using $ in an expression outside of segment block or struct/union was
not rejected; regression test equate28.aso.
- regression in v2.06-2.09: use of an absolute external in an arithmetic
instruction may have suppressed generation of opsize prefix; regression
test extern12.asz.
- EXITM directive inside a macro did not "fix" if-nesting-level issues
caused by the usage of GOTO; regression tests goto1.asm and goto2.asm.
- LOW32 operator in 64-bit didn't always set 32-bit address fixup;
regression tests offset9.asm, offset11.asm.
Other changes:
- CodeView symbolic debug info will contain array records.
- CodeView symbolic debug info: Anonymous structs are now "unfolded";
this is a work-around for the MS debug engine.
- Option -Zi got an optional numeric argument to control the extend
of debugging info that is emitted.
- support for register variables in CodeView debug info (FASTCALL).
- OPTION CODEVIEW added.
- -pe: field TimeDateStamp in file header and in export directory now set
to current date & time.
- -pe: some fields in optional header and section header rounded up to
alignment boundary to satisfy MS COFF specs.
- directive LABEL syntax extension: optional array size argument.
- Warning displayed if line number info is emitted for a segment without
class 'CODE' ( Masm compatible ).
- for improved Masm-compatibility, PUSH|POPCONTEXT ALL does no longer
comprise PUSH|POPCONTEXT ALIGNMENT.
- samples Win32Tls and ComDat added.
- -coff: support for COMDAT sections added.
- -coff: cmdline option -zlp added.
- if the file behind @ cmdline option cannot be opened, a FATAL error is
emitted ( Masm compatible ).
- the register swapping in indirect addressing mode, which was previously
done only if option -Zg was active, is now the standard behavior ( Masm
compatible ).
12/02/2012, v2.09:
Bugfixes:
- setting the value of an assembly-time variable to an alias didn't
reset bits 32-63 of the value (see regression test equate23.asm).
- an undefined symbol in the argument of an assembly-time variable
wasn't always flagged as error.
- the difference of two labels was assumed to be a constant, even if one
or both labels weren't defined (yet). This caused problems if the result
was used in a preprocessor expression or as argument for an
assembly-time variable (see regression test equate22.aso).
- multiple consecutive expansion operators (%) in a macro argument were
rejected.
- comparing two types for (in)equality didn't work in all cases.
- MZ format: values changed by OPTION MZ affected further modules
assembled with -mz.
- regression in v2.08(a): equates with a string value may have been stored
as text macro, althouth the string value fits in 32-bit.
- Win64: the type of expression <struct>.<member> wasn't ignored if such
an expression was used as an argument for INVOKE.
- regression in v2.7-2.08a: a type behind a dot was rejected in some cases
if it didn't match the current type; it must be handled like a type
coercion.
- a struct member with a TYPEDEF type did accept a literal as initializer
without complains. An error occured only if the struct was instanced.
Now a warning is displayed at the struct declaration.
- THIS operator didn't handle structured types correctly.
- SIZE and LENGTH operator returned wrong values if the first expression
contained DUP with an argument of more than 1 item.
- -Zd, -Zi option, COFF format: duplicate entries for static procs may
have occured in symbol table.
- regression in v2.07-2.08a: an explicit type didn't override the assumed
type if OPTION OLDSTRUCTS was set (regression test dotop4.asm).
- OMF format: both communal variables and externals with alternate names
in a module made the assembler create an invalid object module.
- "ifdef FLAT" was always true.
- current prolog and epilog settings weren't reset for each pass.
Actually, this was only a problem if FASTPASS wasn't active ( JWASMR ).
- COFF: .file entry in symbol table was name & extension only.
- 64-bit: for non-FRAME procs, OPTION WIN32:2 (introduced in v2.08) didn't
work if there were register contents to be saved via the USES phrase.
- 64-bit, OPTION WIN64:1: just fix arguments were stored in shadow space,
no "VARARG" arguments.
Other changes:
- JWASMR.EXE: now compiled without support for SSSE3.
- new output format PE and cmdline option -pe added.
- samples Win32_8, Win32_8m, Win64_8, Win64_9a and Win64_9d added.
- tool res2inc added.
- option -Gr ( fastcall calling convention ) added.
- struct initialization does no longer generate code.
- Msvc64.mak added.
- support for Intel VMX extensions added.
- support for AMD SVM (AMD-V) implemented, inactive.
09/07/2012, v2.08a:
- result of a macro function was expanded further even if the final result
was to be enclosed in <> (see regression test expans36.asm).
- expansion of EXITM argument wasn't handled fully Masm-compatible in v2.08
if it contained one or more '!' (see regression test expans37.asm).
08/29/2012, v2.08:
Bugfixes:
- forward references of structures in an expression may have failed
( regression test assume7.aso ).
- if C-style expressions in runtime conditional directives were too
complicated, the generated code may have caused 'symbol not defined'
errors ( regression tests rtcond3.asm, rtcond4.asm ).
- if the argument of the ASSUME directive was a segment register,
the accepted variants of expressions behind the colon was more
restricted than Masm's.
- expansion operator % at position 0 in a line with a macro procedure
call caused a syntax error if nothing was expanded.
- absolute externals were rejected if they were used to initialize a
1-byte variable ( regression test extern8.asz ).
- identifiers inside quoted strings were expanded if the expansion
operator % was at position 0.
- OMF, MZ format: if an assembly-time variable that contained an address
was used in code or data, and the variable's content was later changed
to a number, the assembler emitted either error "missing segment ..."
(OMF) or created wrong code (MZ).
- a text macro as label for INSTR was rejected.
- if a conditional assembly directive occured after expansion only, it
wasn't detected.
- another "corrupted listing"-bug fixed.
- macro parameters and locals weren't detected in quoted strings of macro
lines if the substitution operator & was located AFTER the name only.
- code labels in front of macro procedure invokations were parsed after
the macro arguments were evaluated.
- syntax [<reg|const>+<reg>.<type>].<member> wasn't accepted.
- FASTCALL (MS VC style): if the size of an argument to be stored in a
register didn't fit, an error occured.
- JWASMR.EXE: stack size was too small to handle deeply nested macros;
stack increased from 20 to 33 kB.
- OPTION EPILOGUE: a RET within a user-defined epilogue macro wasn't
translated to RETF if the procedure was FAR.
- JWASMR.EXE, INCBIN directive: optional arguments <offset> and <size> were
limited to 16-bit.
- -nm option: this option to set the "module name" did instead set the
name in the OMF THEADR record. Now it sets the true module name, while
the OMF THEADR record will contain the filename.
- in .IF blocks, multiple .ELSE branches weren't rejected.
- SIZEOF and LENGTHOF did return 0 for data items created with the LABEL
directive.
- values for equates were generally rejected if their magnitude exceeded
32-bits. Now the value is rejected only if it's a plain number,
values of expressions may be 64-bit wide.
- a PURGEd macro may have emitted warnings or errors about missing or too
many arguments.
- a scale factor of 1 allowed the register to be used as base register if
needed. However, any scale factor must enforce the register to be used
as index register.
- 64-bit: default type of parameters and locals was QWORD, but Masm (ML64)
uses DWORD.
- AVX: a few instructions didn't accept an unsized memory operand,
although the size should have been guessed; and a few instructions did
accept an unsized memory operand, although the size couldn't be guessed.
- regression in v2.07: option -Fd=file didn't write all necessary entries
in this version.
Other changes:
- GccWin64.mak added; makes a 64-bit JWasm Windows binary with MinGW-w64.
- IntelC32.mak, IntelC64.mak added; create 32/64-bit JWasm Windows binary
with the Intel compiler.
- optional support for assembly code generated by Intel C++ compiler.
- samples Bin2Inc.asm, Win32_6w.asm, Win32Drv.asm and Win32DrvA.asm added.
- compatibility of -Zm cmdline option ( and OPTION M510 ) improved: the
precedence of [] and () will change from 1 to 9, similar to Masm.
- %OUT directive supported.
- @CatStr 20-argument-limit removed.
- OPTION WIN64 got a new switch ( called: INVOKE Stack Space Reservation )
to autodetect stack space required by INVOKEs within a procedure.
- INVOKE of a FASTCALL (MS VC style) proc: optimization implemented to
avoid to load a register with itself (mov ax,ax).
- extended option -Zg: register are swapped in indirect addressing.
For details see option -Zg in the documentation.
07/21/2012, v2.07a:
- regression in v2.07: for absolute externals, a magnitude was assumed
that may have been too large, resulting in error 'Initializer magnitude
too large'.
- check for multiple overrides in expressions was too rigid in v2.07.
07/02/2012, v2.07:
Bugfixes:
- ELF format: size of .bss segment wasn't set.
- ELF format: segments of class "CONST" weren't marked as read-only
in the ELF module.
- segment attribute INFO wasn't handled for ELF.
- Win64: in v2.05-v2.06, VARARG didn't work for the - first 4 - register
arguments.
- when a procedure's prologue and epilogue code was generated, it was
assumed that radix was 10.
- if the size of a byte array in a structure was defined by the length
of a quoted string initializer, it wasn't marked internally as array
and hence the initialization of data items of this type may have been
wrong.
- it wasn't checked if a string initializer for a simple byte field
in a struct was too long.
- if a struct contains fields with negative offset, the struct's size
was calculated incorrectly.
- JWASMR.EXE: in a few circumstances, negative constants were rejected.
- in v2.04-2.06, it wasn't detected if a group contained an undefined
segment.
- INVOKE: if the argument for a VARARG parameter was a structure, it
was rejected in some cases.
- a line that contained both a comment and a directive which triggered
source line generation (INVOKE, hll directives, ... ) messed up the
listing.
- EQU/= directive: optional type coercions weren't stored, just the
value of the constant.
- FLAT, USE32 and USE64 segment attributes were always accepted, no
check for compatible cpu was done.
- fixups for assembly time variables wasn't correct if the variable
had type "far".
- output format MZ: there was no warning when a 16-bit group's size
exceeded 64 kB.
- OMF output format: many publics in a module may have corrupted
the object module.
- if a struct member was operand for the SEG operator, the member's
offset within the struct was used as addend for the segment fixup.
- calling convention FASTCALL for 16-bit MS C was implemented faulty.
Registers aren't CX and DX, but AX, DX and BX.
- if -Zi was set and a segment had size 0 and a label (empty proc),
the resulting coff object module had errors.
- Win64: .pdata information may have been incorrect if multiple code
sections with SEH data were defined.
- handling of standard register ASSUMEs in the expression evaluator
were not compatible with Masm.
- Win64: in v2.06, the space for local variables was calculated
incorrectly if OPTION FRAME:AUTO was set, an odd number of GPRs &
no XMM registers were included in the USES list.
Other changes:
- IF[N]DEF and .ERR[N]DEF directives: argument may be a structure and
member name, separated by a dot.
- cmdline option -Fd: filename argument for this option is no longer
mandatory for COFF output format.
- FADDP, FMULP, FDIV[R]P and FSUB[R]P variants with no arguments added.
- COFF/ELF: missing support for segment attribute ALIAS added.
- for better Masm compatibility, memory operands with size
1 (PADD[S|US]B), 2 (PADD[S|US]W), 4 (PADDD) and 8 (PADDQ) are accepted.
07/22/2011, v2.06e:
Bugfixes:
- ELF64 format: in v2.05-v2.06d, addends weren't handled correctly.
07/02/2011, v2.06d:
Bugfixes:
- 64-bit: in v2.05-v2.06c, a relocatable constant was often assumed
to have a magnitude of 32, thus accepting operands which are invalid
( "mov m64, offset label" or "push offset label" ).
06/29/2011, v2.06c:
Bugfixes:
- v2.06-v2.06b, directives DB, DW: if the result of a subtraction of
2 labels ( dw label1 - label2 ) was negative, it was rejected.
06/28/2011, v2.06b:
Bugfixes:
- struct fields that were forward referenced may have caused warnings
or errors in v2.06-v2.06a.
- in v2.04-v2.06a, if a pointer to a struct was redefined and the
redefinition used a type alias, the redefinition failed (see
regression test types5.asm)
06/26/2011, v2.06a:
Bugfixes:
- in v2.06 was a regression for IMUL with 3 operands: if the third
operand's value was 127 < x < 256, the instruction was encoded
incorrectly.
06/26/2011, v2.06:
Bugfixes:
- relative pathes for filenames containing '/' may have caused
problems in non-Unix versions.
- register "assumes" on the right side of the binary '+' operator
were ignored.
- 64-bit: in v2.05, "MOV <reg>,offset <label>" was created with a
32-bit immediate (and fixup).
- JWASMR.EXE: struct sizes > 32767 caused problems.
- for RECORD types used in an expression, the default value must be the
record's mask, not the record's size in bytes.
- offset of a struct member may have been calculated wrongly if the base
was just a type (not a variable) AND the first member also had a
struct type ("mov eax, <struct_type>.<mbr>.<mbr>").
- inside struct declarations, a '?' was accepted as initializer of struct
members.
- segment combine type COMMON was displayed as '?' in listing.
- in v2.00-v2.05, PUSH/POP of a 64-bit memory operand wasn't rejected
in 16/32-bit code.
- in v2.05, quoted filenames in the cmdline didn't work.
- division operator '/' did interpret operands as unsigned values.
- instructions BT, BTC, BTR and BTS did accept memory byte operands.
- instruction PALIGNR wasn't encoded correctly.
- OPTION RENAMEKEYWORD: restoring of the keywords failed.
- instructions INSx and OUTSx weren't encoded correctly if arguments
were given.
- INVOKE, 64-bit: float constants may have caused a GPF.
- INVOKE: size check for constants was missing.
- in v2.05, indirect addressing may have failed with 'structure field
expected' if address was in format [reg].<member>[reg].
- an erroneous redefinition of a RECORD type may have caused a GPF.
- if multiple files were assembled with different output formats,
some combinations didn't work as expected due to unwanted side
effects.
- LABEL directive: code labels (NEAR, FAR, PROC) cannot be defined
anymore if CS is assumed ERROR. Previously this check was done only
when the label was defined through a trailing colon.
- operator THIS was accepted in expressions outside segments.
- XLAT, XLATB: memory operand of any size was accepted.
- IMUL: syntax check was sloppy.
- CMOVcc: byte registers were accepted as first operand.
- if an instruction has just a memory operand, but with multiple
possible sizes, no error was emitted if size of current argument
was unspecified.
- in IF blocks, multiple ELSE branches weren't rejected.
- size of fixup for absolute externals may have been wrong in a few
cases ( i.e. second operand of BT[c|r|s] instructions ).
- check for REAL4 initializer limits was missing.
- arrays in unions weren't taken into account with their full size.
- it wasn't checked if names of fields of anonymous struct members were
already used in a struct.
- magnitude test of numbers wasn't strict enough.
- in v2.05, if the argument of EQU was a number with a
magnitude > 32 bits, the equate wasn't created as a text macro.
- operator DUP: if initial value was a quoted string and size of the
data item was > 1, every second repetition was incorrect.
- 64-bit: max. width of RECORD was 32 - changed to 64.
- 64-bit: if OPTION FRAME:AUTO was set and a XMM register was added
in the USES list or a PROC, the offsets of local variables wasn't
calculated correctly and the generated epilogue may have used a wrong
value to restore RSP.
- if a text macro, defined via cmdline option -D, was also defined in
the source and the value of both definitions was an empty string,
a GPF did occur.
- HADDPD, HADDPS, HSUBPD, HSUBPS: variant with m128 as second operand
was rejected.
- 64-bit: PEXTRQ/PINSRQ were encoded incorrectly if a m64 operand
was destination or source.
- syntax 'INVOKE <struct_name>.<mbr>[reg]' caused a GPF in v2.05 (and
didn't work in v1.96-v2.04).
- expansion of macro arguments changed so text macros are expanded
earlier ( needed in cases when a macro argument was a text macro
and the value of the text macro was a macro function call - see
macparm.asm regression test ).
Other changes:
- cmdline option -Sf added.
- OPTION RENAMEKEYWORD, OPTION MZ: syntax changed. Both options used
comma-separated values, which made it impossible to use them in a
"multiple-option" line.
- operators LOW32/HIGH32 supported.
- INVOKE: 64-bit constants (integer and floating-point) supported as
parameters.
- Value of predefined text macro @Version changed from <615> to <800>.
- OC.mak added to support the Orange C compiler (LadSoft).
- result of SHL operator is now 64-bit, same as with Masm v8+.
- OPTION DLLIMPORT added.
- cmdline option -Fd added.
- cmdline option -Fr (set error file name) changed to -Fw, since
option name -Fr is already used by Masm (limited browser info).
- instructions XSAVE, XRSTOR, XGETBV, XSETBV, XSAVEOPT supported.
- AVX instruction set supported.
03/02/2011, v2.05:
Bugfixes:
- PROC directive: it wasn't checked that VARARG parameter was last
parameter.
- ASSUME directive: using an arbitrary pointer type as argument
didn't work as expected.
- CVTSI2SD, CVTSI2SS: memory operand could be of any size. Also, if
it was m64 in 64-bit, no REX-W prefix was generated.
- MOVD: 64-bit memory operand wasn't accepted in 64-bit mode.
- PINSRW: memory operands of any size were accepted.
- in v2.04, a macro name which was located behind a '::' wasn't
expanded, which usually resulted in a syntax error.
- "undefined" types may have caused a GPF if -Zi was set.
- some errors fixed in INVOKE support of Open Watcom fastcall register
calling convention.
- most conditional error directives did emit their errors in pass one,
which was too early.
- there was a risk that macro functions in an EQU argument were
expanded (if the macro invocation was hidden in a text macro).
- check for conflicting parameter types for PROC/PROTO wasn't as
rigid as Masm's.
- EXTERN and EXTERNDEF didn't accept prototype type symbols.
- prologue code generation was triggered slightly differently compared
to Masm.
- syntax check of macro "local" lines was too sloppy.
- when searching macro parameter and local names in macro lines, the
search was always case-sensitive, ignoring current case-mapping
setting.
- ELF64 format: relocations were stored in sections of type SHT_REL.
Changed to SHT_RELA.
- in v2.04, SIZE operator might have returned wrong results for
structured variables (SIZEOF had no problems).
- in v1.93-v2.04, initialization of an array of structures may have
given a wrong result if both DUP and comma operators were used.
- check if a data definition directive was preceded by a code label
- which isn't allowed without -Zm option - wasn't fool-proved.
- the tokenizer did scan numbers not exactly like Masm does, which
caused problems if a number was immediately followed by an identifier.
- MZ format: segment fixups for a segment in a group were wrong if both
the group and the segment weren't located at 0.
- INVOKE, 16-bit code, VARARG parameter: in v2.04, if argument was a
32-bit register, register SP was adjusted wrongly after the call.
- it wasn't checked if GOTO labels inside macros were reserved words.
- INVOKE, 64-bit Windows: in v2.04, it wasn't possible to call functions
which had a VARARG parameter.
- PURGE directive: directive arguments weren't expanded.
- preprocessor directives [ELSE]IF[E] weren't always able to detect
undefined symbols in their argument.
- EXITM: syntax check of the directive's argument wasn't too strict.
- SIZESTR: the directive's label wasn't expanded.
- GOTO: a macro label placed just before the ENDM line wasn't found.
- PUSH/POP: there was no error msg when the argument was a structured
variable with an unsuitable size.
- expression evaluator was unable to handle floating-point constants.
Unary operators +, -, OPATTR and .TYPE are supposed to accept those.
- JWasm's dot operator (.) accepted arguments that Masm does only if
OPTION OLDSTRUCTS is active.
- in a few cases the end of "undelimited" strings wasn't detected.
This mostly applies to string macros (@CatStr) used as arguments
for other macros.
- "assumed" predefined types were ignored by the TYPE operator.
- in v2.03-2.04, an "empty" argument in a macro VARARG parameter list
did reset the list.
- if the expansion operator (%) was used to convert a numeric expression
to text. it was always handled. This was an error, because it is
supposed to be accepted for arguments of preprocessor directives or
macros only.
- line concatenation triggered by a comma as last token wasn't fully
Masm-compatible: if the line is an instruction, a comma should NOT
trigger the concatenation. OTOH, if the comma is a result of a
(text) macro expansion, it should trigger concatenation.
- if a source file argument wasn't the first and the file couldn't
be found, a GPF occured.
- INC/DEC: in v1.94-2.04, "unsized" memory operands were accepted.
- SHLD/SHRD: syntax check was too sloppy.
Other changes:
- cmdline option -eq added.
- cmdline option -zld added.
- INVOKE support for Open Watcom register calling convention enabled.
- OWWinDll.mak and MsvcDll.mak added to create JWasm as a Win32 dll.
- source code in listing file now starts at column 32.
10/17/2010, v2.04c:
Bugfixes:
- in v2.04-2.04b, a type coercion of NEAR or FAR for a memory operand
(sometimes used for indirect calls or jumps ) didn't work correctly.
10/08/2010, v2.04b:
Bugfixes:
- in v2.04 + v2.04a, if IMUL's second argument was a forward reference
and a third argument was also given, then error 'invalid instruction
operands' was emitted.
- an empty PROC located outside of a segment block didn't emit error
'Must be inside segment block' - and in v2.04 additionally an access
violation did occur.
- using ALIAS names in expressions was rejected in v2.04. Previously,
this wasn't rejected, but fixups were wrong, which wasn't better.
10/05/2010, v2.04a:
Bugfixes:
- in v2.04, if operator OFFSET was used in an indirect addressing
expression ( mov ax,[bx+offset var] ), the variable's type information
wasn't removed.
- in v2.04, value of assembly time variables were evaluated wrong if they
were forward referenced.
- in v2.04, error 'symbol type conflict' did occur if a type was defined
twice, first as an arbitrary type, second as a scalar type, and the
arbitrary type was just an alias of the scalar type. Example:
type1 typedef ptr
type2 typedef type1
type2 typedef ptr
- operator SEG didn't enforce the argument to have size WORD.
10/04/2010, v2.04:
Bugfixes:
- ELF fixups for 16-bit relative offsets (GNU extension) were wrong.
- PUSHCONTEXT|POPCONTEXT didn't accept multiple arguments.
- a code segment defined with simplified segment directive .CODE,
with a name argument and which was added to a group BEFORE the
definition, was created with default attributes.
- MZ format: segment fixups in the MZ header weren't always calculated
correctly.
- ALIGN, EVEN: "filler" bytes were emitted unless the segment was
"absolute" or "bss". Now this is done only when data or code was
emitted just before the directive.
- COFF format: JWasm expected to use the ".drectve" section exclusively.
If it was defined within the source, an error occured.
- COFF format: option -SAFESEH didn't emit a "@feat.00" absolute
symbol in the object module, as requested by the MS COFF specification.
- JWASMR.EXE: v2.03 often fell into an endless loop due to an error in
fixup management for backpatching.
- in v2.03, constants with -65536 < value < -32768 were not accepted
for 16-bit targets in MOVs.
- a label was accepted even when there already existed a proto with the
same name.
- operator TYPE ignored a possible coercion for a type argument.
- a duplicate RECORD definition was rejected, even if both definitions
were identical.
- an absolute external used as a byte immediate may have caused invalid
code to be generated ( extern x:abs - or al,xx ). MOV and PUSH were
not affected, though.
- in v2.00-2.03, PROTOs were listed in the "Symbols" section, not in
the "Procedures" section.
- for COMMunal variables, there was no check if the symbol was defined
with a different kind already.
- if .STARTUP or .EXIT occured before any code or data definition
lines, the code generated by those directives might have get
truncated.
- INVOKE: a FWORD parameter caused an error if the argument to be
pushed was a constant.
- LOCAL and INVOKE: a local or a parameter of size 0 confused the
assembler.
- MOVD didn't accept a REAL4 memory operand as second argument.
- EXTERN directive: altname was ignored if external was a prototype.
- EXTERN directive: altname symbol was rejected if it was external.
- OMF output format: no WKEXT comment records were written for
EXTERNal items with an alternate name.
- if floating-point emulation fixups were to be generated, there was
no NOP inserted before FWAIT if current CPU was 80386 or better.
- INVOKE, VARARG parameter: if cpu was < 80386 and a constant value
which didn't fit into a word was to be pushed, JWasm complained.
- INVOKE, VARARG parameter: the calculation of the stack adjustment
value was wrong in the following cases:
a) when a byte register was pushed
b) when the argument consisted of 2 registers ('ds::bx')
- JWASMR.EXE: freeing a PROC's local items was done with the wrong
linked list. This often resulted in an abnormal termination.
- in v2.03, if Win64 output format was selected, a GPF did occur if
a stack variable was used as an argument for INVOKE.
- SHR and SHL operator didn't reject negative shift counts. Also,
shift counts >= 64 returned compiler-dependant results.
- if a text literal defined with SUBSTR was referenced before definition,
the definition failed.
- INVOKE for Win64 didn't work for VARARG parameters.
- syntax ASSUME <reg>: ERROR|NOTHING rejected 8-bit registers.
- directive ASSUME: argument types for segment register assumes
weren't restricted to segment, groups or segment registers.
- codeview debugging info: in v2.02-2.03, type info for structures and
unions wasn't written. Without this info, it wasn't possible to examine
the contents of structure members in a debugger.
- text macros used to initialize an byte array within a struct did cause
error 'invalid symbol type in expression' it the macro wasn't enclosed
in angle brackets.
- in v2.01-v2.03, it was possible to redefine a numeric equate if it
was calculated as the difference of two labels.
- on certain conditions the expression evaluator skipped type information,
and emitted a warning then. Example: mov [eax-<n>](<type>.<member>),0
- JWASMR.EXE: setting radix to 16 made the assembler accept no numbers
anymore.
- 64-bit: LAR and LSL weren't implemented ML64-compatible, they accepted
DWORD/QWORD memory operands.
- in a few cases (where JWasm assumed forward references to be labels,
which later turned out to be numbers) there was a risk that a short
destination for a jump wasn't detected and hence not the smallest
possible code was generated.
- comparisons of TYPE expressions may have failed for expressions with
type coercion.
- in v2.03, false conditionals were always listed (.LISTIF).
- in v2.00-v2.03, a code label in front of conditional directives gave
syntax errors.
- directive TYPEDEF: type conflicts of some pointer types were undetected.
Other changes:
- OPTION NOSIGNEXTEND supported.
- OPTION WIN64 added.
- new cmdline switch -Zv8.
- INVOKE generates smaller code for constant arguments with 8086 cpu.
- INVOKE for Win64 watches if register parameter values are destroyed.
- INVOKE for Win64: type checking of arguments is now more strict.
- to increase Masm-compatibility, floating-point initialization with
"real-number designator" (R) supported. Example: "var REAL4 3f800000r".
- INVOKE support for Open Watcom fastcall register convention
implemented ( disabled by default ).
- Djgpp variant of COFF supported ( disabled by default ).
- JWASMR.EXE: stack size increased from 16 kB to 20 kB.
08/03/2010, v2.03:
Bugfixes:
- invalid cmdline option behind source filename caused a GPF.
- expressions in a data field initializer were evaluated when the
structure was instanced. This gave incorrect results or assembly
errors if the expression contained an assembly time variable
( including $ ).
- INVOKE directive: if register EAX|RAX was used for indirect addressing
of a parameter, there was no check if the content of the register has
been overwritten previously due to an ADDR operator.
- INVOKE directive, 64-bit: if a parameter beyond the first four was an
address which had to be loaded into register RAX to store it onto the
stack, the generated source was either invalid or a GPF occured.
- TYPEDEF directive: pointer definitions did use the default size for
data pointers, which isn't correct if the pointer is defined as a
function pointer and memory model is COMPACT or MEDIUM.
- 64-bit: assembly time variables or immediate operands with a value
magnitude > 32 bits were rejected.
- macro expansion: expansion operator at the start of a line and more
than one macro function call within this line might have resulted
in garbage.
- DUP operator: count (first operand) was rejected if it was a string.
- float initializer in BSS segments wasn't rejected.
- OMF format: when a listing was to be written (-Fl) and a large array
was defined, a GPF might have occured.
- error 'Symbol redefinition' occured if an equate's expression contained
another equate which was the result of a subtraction of 2 labels AND
a phase error caused this difference to change.
- comments weren't displayed in listing.
- in v1.96-2.02, if cmdline option -mf was set, the cpu wasn't
automatically set to a 386 as it was done before.
- format COFF: symbols defined as weak externals were created as normal
externals if the EXTERN directive was used for the definition.
- 64-bit: opcodes MOVSXD and CQO (both 64-bit) were missing.
- 64-bit: opcode CDQE was encoded without the REX prefix, thus it was
a CWDE in fact.
- 64-bit: QWORD type coercion for an immediate operand didn't force the
operand's size to 64-bit.
- 64-bit: MOVs with a segment register as operand didn't accept 64-bit
registers as the other operand ("mov ds, rax").
- 64-bit: SLDT, SMSW and STR didn't accept 32- and 64-bit registers as
operand.
- a displacement which didn't fit into 32-bits caused error 'Constant
value too large' in versions 2.00 - 2.02. This has been changed to a
warning (level 3) in 16- and 32-bit. In 64-bit code, it is still an
error.
- In expressions, types combined with the open (square) bracket operator
( "mov eax, DWORD [ebx] ) weren't rejected.
- comparisons of TYPE expressions did compare the type's size only.
- Name of a macro proc used as a macro argument caused a syntax error.
- for indirect calls/jumps, a struct field used as displacement didn't
qualify the type of the call/jump, resulting in an error msg.
- A .MODEL directive which occured AFTER code definition lines may
have confused JWasm.
- in JWasm v2.00-2.02, when a RECORD variable had to be initialized,
there was a risk that an erroneous padding byte was added.
- initialization of DWORD/QWORD items with constants in string format
may have been incorrect due to wrong little-endian conversion.
- empty lines - or lines containing just a comment - in macros weren't
counted, thus a wrong line number might have been displayed if an
error occured inside a macro.
- name arguments for .DATA? and .CONST were always accepted, but
ignored. Now they are accepted only if -Zne isn't set and the name
is NOT ignored then.
- 64-bit: for -win64, default for GS register assumption was "ERROR".
Assumption changed to NOTHING.
- 64-bit: JWasm always used RIP-relative direct addressing mode, even
if there was a segment override with a segment register which wasn't
assumed to be FLAT.
- 64-bit: encoding of indirect addressing with base registers R12/R13
and no index registers wasn't correct.
- 64-bit: encoding of indirect addressing with base registers
RBP/R13/R13D + index register and no displacement wasn't correct.
- 64-bit: register R12D was rejected as base for indirect addressing.
- PURGE made macros "invalid" (it should just delete the macro content).
- listing of macro invokations started with a "non-existing" empty line.
- TEXTEQU: if the % operator was to evaluate a numeric argument which
contained other text equates, the equates were expanded incorrectly.
- TEXTEQU: the % operator returned a signed value for numeric arguments.
For strict Masm compatibility, it has to be an unsigned value.
- OPTION DOTNAME: in v2.0-v2.02, this option may have caused macro
parameters not being recognized in macro source lines if the parameter
was preceded by a dot.
- in v2.0-v2.02, the % operator didn't work reliably for VARARG macro
arguments.
- a text macro which contained a macro function call and extra chars
might not have been expanded correctly if it was used as an argument
in one of the string directives.
- a GOTO to an undefined macro label didn't display an error.
- macro locals used as macro labels didn't work.
- in v2.00-2.02, there was a risk that JWasm generated a near jump
( or an "extended" conditional jump if cpu is < 80386 ) when a short
(conditional) jump would have been ok.
- ALIGN directive without argument inside struct definitions created
bad offsets.
- left part of equates in listing sometimes got copied to the next line.
- no warnings were emitted on warning level 3+ if procedure arguments
or locals weren't referenced.
Other changes:
- OW v1.9 used to create the JWasm binaries.
- opcode RDTSCP supported.
- option -nc wasn't documented.
- the (average) number of passes needed to assemble a source has been
reduced. This should also have a positive impact on assembly time.
01/19/2010, v2.02:
Bugfixes:
- in v2.00-v2.01, option -Zg disabled alignment padding for structures.
- in v1.96-v2.01, if argument of a PUSH immediate was a segment or
group value, the short 'byte' form of the PUSH opcode was generated,
which - in conjunction with the fixup for this value - resulted in
bad code.
- literal-character operator (!) was ignored within arguments of
directives IFIDN[I] and IFDIF[I].
- literal-character operator (!) wasn't handled in literals of .ERRxx
directives.
- FOR/IRP/FORC/IRPC: parameter placeholder names beginning with a '.'
were always rejected.
- FORC/IRPC: additional items after the literal argument weren't
rejected.
- in v2.01, arithmetic instructions with a forward memory reference
as first operand and an immediate value as second operand were
rejected if cpu was < .386.
- for formats other than OMF, the buffer which hold the contents of a
segment might have been allocated too small if the segment was a
code segment and contained forward references but no labels.
- OMF format: there was a risk that WLink refused the object module
generated by JWasm because size of code sections did shrink in
assembly passes > 2 but file size wasn't adjusted accordingly.
- CMPSx string instruction: if first operand had a DS prefix, it was
generated, although it's superfluous.
- XCHG with 2 register operands: encoding of registers differed from
Masm's (unless one operand was AX/EAX).
- in v1.95-v2.01, MMX/SSE instructions did emit prefix byte (0x66) in
16-bit code if one operand was a 32bit standard register.
- opcodes CALL/JMP in 64-bit code: rex prefix wasn't emitted if operand
was a register, which caused "call r8" to be encoded like "call rax".
- 64-bit indirect addressing: if memory operand was second argument and
address used both base+index register, the REX_X bit wasn't set.
- in 64-bit code segments, the filler bytes created by ALIGN/EVEN
directives weren't valid NOPs in all cases.
- there was no check whether type coercions for registers ( DWORD PTR
EAX ) were consistent.
- for all formats besides OMF, there was no message if a 16-bit segment
exceeded 64 kB.
- runtime conditionals: the 'logical NOT' operator ! did not invert
logical operators && and ||.
- INVOKE directive: for models with default far data pointers ( COMPACT,
LARGE, HUGE ), the ADDR operator didn't make the segment part to be
pushed if parameter had the VARARG attribute.
- OMF format: in v2.00-v2.01, there was a risk that a fixup record might
have contained a fixup for the NEXT ledata record, which is invalid.
- OMF format: COMMunal variables with size > 128 caused object module
corruption.
- OMF format: if an array of far COMMunal variables exceeded 128 items,
a fatal error ("internal error in omf.c") occured.
- 16-bit floating-point fixups: generated fixup frame specifier differed
from Masm's ( F4 [FRAME_LOC] vs F5 [FRAME_TARG] ).
12/12/2009, v2.01:
Bugfixes:
- shift and rotate opcodes accepted any 8-bit register as second
argument. If it wasn't CL, wrong code was generated.
- IN/OUT opcodes accepted any 16-bit register as source/target, not
just DX. If it wasn't DX, wrong code was generated.
- an unnecessary DS prefix for OUTS string instruction wasn't removed.
- 16-bit indirect addressing-mode with a scale > 1 wasn't rejected and
invalid code was generated.
- if errors occured JWasm still returned error code 0.
- indirect CALL/JMP needed a size, even if -Zm was set.
- with -Zm, the offset of a struct member wasn't correct if the struct
was nested and the member was referenced without the 'dot' operator.
- in v2.0, error 'Constant value too large' may have occured if the
SHL operator was used in expressions to define an immediate value
and the result didn't fit in 32-bits.
- directive '=': expression wasn't rejected if it contained externals.
Now error 'Constant expected' is displayed.
- JWASMR only: detecting the size of an immediate operand often failed,
which then gave error 'immediate data out of range'.
- segment/group override used in an argument for the OFFSET operator
was ignored.
- format BIN: offsets were always group-relative (OPTION OFFSET:SEGMENT
was ignored).
- arithmetic instructions with immediate operand: the signed (=shortest)
variant of the instruction wasn't generated if the immediate operand
was a negative WORD value.
- absolute segments weren't correctly displayed in the listing file.
- formats MZ: fixups with references to absolute segments weren't
handled correctly.
- SSE2 CMPSD/MOVSD: memory operand of type QWORD was rejected.
- SSSE3 instructions: indirect addressing with ESP didn't emit the
SIB byte.
- in v2.0, a struct field with a name which matched an arbitrary type
was rejected if the type of the struct field was a predefined TYPE
(example: name1 WORD ? ; [<name1> is both a struct field name
and an arbitrary type name] ).
- OMF format: if the LNAME index of a group name was > 255, the link
between the name and the group definition record became broken.
- syntax "EXTERN:" and "EXTERNDEF:" (directive + colon, but no type),
was rejected, but seems to be valid Masm-syntax.
- for PUSHD, only immediate operands were accepted.
- in JWasm, using a text macro before it is defined is to cause
a warning. This worked for text macros defined with EQU only, but
didn't if the macro was defined with CATSTR or TEXTEQU.
- for segment registers, the assume search order in v1.96 and v2.0
didn't match Masm's.
- macro loop directives (REPEAT, FOR, FORC, WHILE) with no data
lines caused a GPF.
- if a text macro contained multiple macro function calls, only the
first one was evaluated on some conditions.
Other changes:
- equates and assembly time variables: magnitude of values has been
increased by 1 bit. Now it's 32bit plus a sign bit - similar to Masm v8.
- multiple overrides in an expression will give a warning.
- if an equate was assigned a PROC, the proc-specific info wasn't stored,
which made it impossible to use the equate for the INVOKE directive.
- instruction sets SSE4.1 and SSE4.2 supported.
- data types MMWORD and XMMWORD supported.
10/12/2009, v2.00:
Bugfixes:
- for output format OMF, the listing contained "random" values of data
bytes in BSS segments.
- syntax check for WHILE didn't reject additional arguments.
- PUSH/POP instruction: a forward reference to a variable caused an
error if cpu was 8086.
- for most MMX and SSE instructions, type of memory operand wasn't
checked too strictly.
- ALIGN for data segments did emit the same bytes as for code segments.
- in 16-bit code, PUSH <imm> with -65535 <= imm <= -129 made JWasm push
a DWORD value or - if cpu was < 80386 - caused error 'instruction form
requires 80386'.
- in v1.96, usage of a not-yet-defined symbol in a data definition may
have caused error "initializer magnitude too large".
- .NO87 had no effect in v1.96.
- OMF format: size of LNAMES record may have exceeded 1024 bytes.
- in v1.96, if -Zm was set, structure fields had offset 0 when they were
referenced without the structure name.
- inside macros, value of predefined symbol @Line was current macro line
number instead of current source line number.
- support for IMAGEREL and SECTIONREL operators was effectively disabled.
- missing quotation mark in strings wasn't flagged.
- JWASMR.EXE: array initialization strings caused a syntax error.
- JWASMR.EXE: value of equates was truncated to 16bit.
- argument of INCLUDE directive was always expanded. Now it's only
expanded if the expansion operator (%) is the line's first character
(Masm compatible).
- -Zp switch was ignored.
- padding of a struct's last member didn't depend on the largest type
of the structure, thus it was incompatible with common C compilers.
- ECHO without argument might have displayed garbage.
- alignment of members of type STRUCT didn't work as expected.
- equate @FileCur always returned the main source filename.
- in v1.96, indirectly calling a function with a different offset
magnitude by type coercion (call PF16 ptr [ebx]) created wrong code.
- the argument of REPEAT was treated as unsigned integer, but should be
a signed integer.
- JWasm complained about a missing <text> argument for IRC/IRPC, but
this is actually a valid syntax.
- If a struct member's name was also a type name and the member's type
was of arbitrary type, a syntax error occured.
- directive ASSUME <reg>:ptr <type> caused an error in pass 2 if <type>
still wasn't defined. Now it's just skipped, which is what Masm does.
- DB directive: empty string argument ("") wasn't rejected if directive
was used without label.
- directives [ELSE]IF[N]DEF without argument caused a warning.
- code generated by runtime conditionals might have been wrong if
expression had the format (<expr> && (<expr> || <expr>))
- INCBIN was ignored if it was first instruction to insert bytes.
- if cpu was 8086, INVOKE failed for constant arguments.
- operators SIZE and LENGTH worked like SIZEOF/LENGTHOF if expression
contained the DUP operator.
- directives INCLUDE, INCLUDELIB and INCBIN: filenames beginning with
a digit may have caused a GPF.
- indirect addressing mode: usage of multiple index registers wasn't
detected in all cases.
Other changes:
- support for 64-bit enabled.
- new cmdline options -win64 and -elf64.
- new cmdline cpu options -7, -8, -9, -10.
- object module is accessed with standard stream functions, low-level
file i/o isn't used anymore.
- format of error/warning msgs is more Masm-compatible.
- directives for 64-bit SEH added (.ALLOCSTACK, .PUSHFRAME, ... )
- OPTION FRAME added.
- type SQWORD supported.
- OPTION DOTNAME | NODOTNAME fully supported (previously NODOTNAME was
ignored).
- directive .SAFESEH and cmdline option -safeseh supported.
- cmdline option -Zd implemented for COFF output format.
- cmdline option -Zi implemented for OMF and COFF output formats.
- cmdline option -zld removed. File dependency records are written
when options -Zd or -Zi are set.
- Masm compatible cmdline option -Zs added, and existing cmdline option
-zs renamed to -zt to avoid ambiguity.
- operators IMAGEREL and SECTIONREL work with BIN format, which makes it
possible to create PE binaries using this format.
- BIN format: initial ORG in any segment will just set current offset.
Prior to v2.0 this was true for the very first segment only.
- ELF32 format: LD extensions for 8/16-bit relocations supported.
- OPTION ELF added.
- PUSHCONTEXT/POPCONTEXT ALIGNMENT added.
- option -j removed.
- directive OPTION RENAMEKEYWORD added.
- optional attribute LABEL for first macro parameter supported.
- macro loop iteration displayed in error msgs.
- expansion of macro parameters improved.
- regression tests added to source package.
- -Zi switch for COFF output format may have caused an exception when
code was written without using PROC/ENDP.
07/29/2009, v1.96a:
Bugfixes:
- JWASMR.EXE in v1.96 contained a bug in the ASSUME directive which
made it unusable.
Other changes:
- JWASMR.EXE is now distributed in a separate package.
07/26/2009, v1.96:
Bugfixes:
- BIN format: fixups related to $ were always resolved to 0.
- offset <seg_name> didn't return the segment's highest offset.
- if ASSUME forward referenced a type, the type's validity wasn't
checked in pass 2 if the directive was located before any code
or data definitions.
- BIN format: in v1.95, a stack segment generally wasn't written, but
this rule has turned out to be too simple. Now a segment isn't written
if the segment itself AND all segments following it don't contain
initialized data.
- BIN format: if .DOSSEG was set, segments might have got lost in the
binary.
- if a macro which contained EXITM was placed behind a code label, the
code label was duplicated, giving error msg "symbol already defined".
- INVOKE directive, cpu 8086: if ADDR operator was used to push the
direct address of a memory variable, a "PUSH OFFSET <address>" was
generated. However, push with immediate operands isn't supported by
this cpu.
- BIN output format: operators LOW and HIGH were rejected.
- OMF output format: in code lines, the HIGH operator was ignored,
resulting in a wrong fixup type.
- cmdline "-Fo<directory>\ *.asm" didn't work reliably, the <directory>
information got lost after the first file had been assembled. Same for
-Fr and -Fl.
- the JWasm versions for DOS 16-bit, OS/2 and Linux had problems if a
cmdline option and its argument were separated by a white space
(i.e.: -Fo Sample.com).
- nesting of response files wasn't handled properly.
- if name of response file contained spaces, it wasn't parsed correctly.
- type coercion within () did force the whole operand to this type.
example: mov (<type PTR ds:[mem_addr]).<struct_field>, ax
- a macro function invoked by EXITM might have caused a line number mess.
- JWasm did complain if a character was found in a number without 'h'
suffix. This is too rigid if current radix is > 10.
- output format COFF, ELF: a buffer was allocated for segments which
contain just uninitialized data. This isn't necessary.
- output format COFF: segments with combine type STACK were marked as
'uninitialized', even if they contained initialized data.
- no error msg was displayed if a non-segment register was on the left
side of the ':' operator.
- no error msg was displayed if a segment register which was assumed to
error was used in an expression.
- if a data label was defined more than once, an error was displayed.
However, this is to happen only if the label's address or type differs
from the previous definition.
- (invalid) fixups were created for data items consisting of a
segment override and a number (i.e. "dw ds:[12h]").
- -fpc option was virtually ineffective because cpu directives also
set a default fpu mode.
- SYSENTER was erroneously marked as a privileged instruction.
- in v1.95, there was a regression if a literal enclosed in <> contained
(double) quotes and was used as a parameter for FORC,IRPC.
- OPTION PROC:PUBLIC caused a syntax error.
- EXITM did restore the line number too late. Thus the macro's line number
was displayed in error msgs, although the macro function itself ran
successfully.
- regressions in v1.95: for SSE2 instructions CMPSD/MOVSD, the code
which was generated wasn't correct.
- no check was done to ensure that index for ST(n) doesn't exceed 7.
- there was no error msg if a third argument was given for instructions
which accept two arguments at most.
- INVOKE: a general-purpose register which was assumed to be a function
pointer wasn't accepted as first argument.
- OPTION OLDSTRUCTS didn't work the way it does in Masm.
Other changes:
- -mz format option added.
- directive OPTION MZ added.
- a segment map was added to the listing file of binary formats.
- undocumented (and useless) cmdline option -7 removed.
- samples Mixed216 and Mixed232 added.
- invalid cmdline options don't abort the assembly process anymore,
just a warning is displayed.
- GccDos.MAK, PellesC.MAK, BCC.MAK and TCC.MAK added.
- the 16bit version, JWASMR, no longer supports -coff and -elf. It
didn't work reliably in v1.95.
- Makefile: creating jwasmd.exe now also works with OW v1.8.
- OW v1.8 used to create the JWasm binaries. Previously it was v1.7a.
- INVOKE: extending a memory argument from word to dword won't destroy
content of register EAX if option -Zg is set.
- experimental support for x86-64 added to the source (not active in
the binaries).
- support for FASTCALL implemented, replaces language WATCOM_C.
- options -zf0 and -zf1 added.
- options -zzo and -zzp renamed to -zs0 and -zs1 for better
name consistency. Option -zs2 added.
- options -fp5 and -fp6 removed. They were useless.
- instruction UD2 added (requires cpu .686)
05/26/2009, v1.95:
Bugfixes:
- listing of items in initialized structures was wrong.
- listing for .STARTUP and .EXIT was messed up.
- optional value behind .EXIT directive wasn't parsed correctly.
- .LISTIF didn't display true conditionals inside macros.
- -Sa cmdline option didn't set .LISTMACROALL
- "if" state wasn't saved/restored if a macro had to be run in a
line with expansion operator at the beginning of the line.
- bit 6 returned by OPATTR was set for local variables only, but
is has to be set for any indirect memory reference related to SS.
- TYPE with indirect memory operand and a type coercion returned 0.
- line continuation caused by a comma as last token did ignore empty
lines. However, an empty line must stop the continuation.
- OPATTR didn't accept expressions as operands which contained the
OFFSET operator.
- if the expression evaluator found a macro name, it changed the
symbol's type to a label. Now error 'invalid symbol type in
expression' is displayed.
- if an INVOKE directive was first line to emit code bytes and was
placed outside of a PROC, the code which was generated was wrong.
- names of locals in macros beginning with a digit weren't rejected.
- using OFFSET operator in 'LEA <reg>,[ OFFSET <symbol>]' was rejected.
- if an array of data items was defined, a terminating comma caused a
syntax error.
- if a term '<variable>.<type>' was found in an expression, it wasn't
handled similar to '<type> PTR <variable>'.
- @InStr and @SizeStr returned result as string in radix 10, but
current radix is to be used instead (which "usually" IS 10).
- AT segments didn't work in v1.94.
- ALIGN directive did emit bytes in BSS and AT segments.
- OMF output format: segment and class names must be converted to
uppercase for both OPTION CASEMAP:ALL and OPTION CASEMAP:NOTPUBLIC.
- syntax check of LABEL directive wasn't restrictive enough.
- labels within structure definitions wasn't rejected.
- TYPE with struct operand returned wrong result in v1.94 if size of
struct was > 8.
- ASSUME did reject forward references to types.
- syntax check for PUBLIC, EXTERN, EXTERNDEF, GROUP, ENDS, LOCAL
wasn't fool-proved.
- @SizeStr's parameter wasn't optional.
- it wasn't possible to define an array of 0 items with the LOCAL
directive, size was silently changed to 1 item then.
- a forward reference to a symbol of RECORD type gave an error.
- the MOD operator didn't check if second operand was zero.
- syntax check for conditional assembly directives did accept invalid
formats.
- value of $ was wrong inside structure or array definitions.
- reserved word '.386C' was missing.
- once the cpu was set > .8086 it wasn't possible to set .8086 again.
- wrong fixup generated for 32bit addressing modes if the symbol was
16bit.
- JWasm got confused if a macro's VARARG parameter did start with a ','.
- in v1.94, OPTION SEGMENT:USE32 set default segment size to USE16.
- JWasm didn't reject an undefined symbol in an expression after IF.
- OPATTR for code labels returned wrong value.
- .NOCREF/.XCREF directives didn't accept arguments.
- type conflicts for symbols which had an additional EXTERNDEF entry
were detected for data labels only.
- IF[N]DEF <symbol> failed if <symbol> was a forward reference.
- ':' operator did clear a type which was set by the PTR operator.
Test case: <type> PTR ds:[0].
- hll expression evaluator did always handle the '()' operator, while
it should handle it only if the expression enclosed contains a
hll operator.
- -D cmdline option didn't tolerate spaces between -D and macro name.
- IF[N]DEF directive didn't work reliably in pass two. This was hardly
noticed because in JWasm all passes except the first one handle
preprocessed input only - usually.
- protection exception occured if a parameter for INVOKE consist of a
register pair (DS::SI) and value of register [E]AX was modified before.
- forward references of assembly time variables were evaluated to 0,
but the value must be the variable's value after pass one is finished.
- in v1.94, data initializer of strings within structures didn't cover
the full array length.
- ASSUME ignored the PTR operator and accepted invalid types for register.
- ENDP didn't complain if tokens were found behind the directive.
- support for WATCOM_C calling convention was 32bit only.
- for WATCOM_C, it was assumed that the caller does stack cleanup if not
all parameters did fit into registers. However, this is true for
VARARG procs only.
- for WATCOM_C, register parameters weren't displayed correctly in the
symbol list.
- output format BIN: fixups might have been written multiple times,
which then caused a bad binary.
- output format BIN: relative offsets (jumps and calls) were calculated
wrong.
- OPTION PROC:PRIVATE made procedures private even if PUBLIC
directives existed for them.
- PROTOs will no longer accept PUBLIC attribute (Masm also rejects).
- a PROC with attribute PRIVATE and a PUBLIC directive for the very
same symbol wasn't rejected.
- empty line in a COMMENT block may have been interpreted as EOF.
- a forward reference to a symbol in a DB directive was rejected
(initializer magnitude too large).
- if two macro params were separated by one substitution operator (&)
and the first param additionally had a & prefix, then the second param
wasn't recognized (and substituted).
- CMPSx string instruction was rejected if two segment overrides were
used. Now it's rejected only if the second one is != ES:.
- CTRL-Z in input files wasn't interpreted as EOF.
- output format BIN: uninitialized variables located at the start of
a segment were skipped.
- output format BIN: stack segment was always written. Now it's written
only if it isn't the last segment.
- if radix was > 10, the literal created by the % operator may have
contained lowercase letters ('a'-'f'), which isn't Masm-compatible.
- if -Zm (OPTION M510) is set, reserved words which were introduced
in "later" cpus should be free to use. For JWasm this still isn't
fully true, but it's now possible to use the names introduced by
MMX/K3D/SSE extensions.
- OFFSET operator applied to a non-relocatable constant wasn't ignored.
- listing of LABEL directive didn't display current offset.
- handling of macro parameters improved so that strings enclosed in
(double)quotes and containing '>' work similiar to Masm.
- OMF format: size of PUBDEF records might have exceeded 1024.
- for errors detected in pass two or later the source filename which
was displayed may have been wrong.
Other changes:
- -Zg option implemented.
- a hash table for local symbols has been implemented since the old
implementation (linked list) was too slow if lots of local labels
were defined.
- OPTION OFFSET:SEGMENT supported.
- GccUnix.mak added, MinGW.mak renamed to GccWin.mak.
- -X option supported.
- warning level for PAGE, TITLE, SUBTITLE changed from 3 to 4.
- instruction FFREEP supported.
- OWDOS16.mak and OWOS2.mak added.
- -zze option added.
- samples Window4, Mixed1 and OS232 added.
12/24/2008, v1.94c, bugfixes:
- multiple filename arguments in cmdline didn't work in v1.94-v1.94b.
12/21/2008, v1.94b, bugfixes:
- initialization of structure date items embedded in another
structure data item didn't work in v1.94/v1.94a.
12/20/2008, v1.94a, bugfixes:
- .LISTALL didn't enable listing.
- ".IF 1" doesn't generate code, which made problems in v1.94.
12/19/2008, v1.94:
Bugfixes:
- INVOKE rejected a byte register if the parameter type was BYTE.
- if additional cmdline options were given in a separate file - by
'@<filename>' - then an exception might have occured.
- syntax 'exitm<>' (no white space after 'exitm') wasn't accepted.
- an external absolute symbol was sometimes forced to 16bit, which
was a problem if the symbol was used in an operand for PUSH.
- include paths set with -I had less precedence than include paths
set in INCLUDE environment variable.
- expression after .WHILE and .UNTIL wasn't optional.
- keywords removed with OPTION NOKEYWORD weren't restored when another
source module was to be assembled.
- if more than one file was to be assembled, there was a risk that
setting the include path by either option -I or environment variable
INCLUDE caused a GPF.
- size information was lost in an expression if a register plus
displacement or scale factor was located AFTER the structure field.
- in COMM directive, a language type followed by the NEAR|FAR keyword
wasn't accepted and caused a syntax error.
- invalid size of memory operands for CALL/JMP was silently changed to
WORD/DWORD.
- substitution operator (&) didn't work for macro function calls if the
expansion operator (%) was first character on a line.
- "TYPE <number>" returned value of <number>. Now 0 is returned.
- "SIZE <simple type>" wasn't accepted.
- invalid fixup types for COFF format were accepted without error message.
- if the filename parameter of an INCLUDE directive wasn't enclosed in <>
and did start with a number, the file wasn't found.
- MASK and WIDTH operators worked with bitfields only, not with RECORD
types.
- if OPTION OLDSTRUCTS was set, multiple occurances of the same struct
definition may have caused error "symbol already defined".
- access to memory locations without fixup, but with a segment override,
was assumed with an offset magnitude equal to current CS, which isn't
necessarily true.
- it wasn't allowed to open a segment which was already "opened".
- initializer for a structure wasn't ensured to be a literal enclosed
in <> or {}.
- the parser didn't distinguish between a single item and an array of
size 1. Since data initialization is to be handled differently for
these cases, this behavior wasn't compatible.
- there was no test for a max. nesting level implemented if a macro
called itself. Usual result was an "endless" loop.
- if option -Fl was set and the assembly source didn't contain any
instructions or data definitions, then all lines were listed twice.
- if a required macro parameter was to be expanded, but expansion failed
due to an undefined symbol, an access violation might have occured.
- expansion of macro function calls in text equates failed if the
string contained a '<', '>' or '!' character.
- OPATTR <literal> returned 36 and OPATTR without operand caused a
syntax error. In both cases OPATTR will now return 0.
- SHORT operator did accept any operand types.
- if a short jump destination was a forward reference and too far away,
the error was displayed when the destination label was parsed. Now the
error is displayed when the jump instruction is parsed.
- environment variable "JWASM" wasn't handled as expected.
- cmdline option -nd didn't work as expected.
- expansion operator in TEXTEQU/CATSTR may have given unexpected results.
- SIZEOF returned double the size for an internal item if it first was
declared by an EXTERNDEF directive.
- since v1.9, warning count was reset for every pass.
- if a macro parameter was expanded due to the expansion operator %, it
didn't work if at the first nesting level a macro function was expanded
and at the next level a text macro had to be expanded.
- numbers > 0xFFFFFFFFh weren't stored as text macros in all cases.
- precedence of operator PTR changed from 5 to 4. This change makes
syntax "TYPE <type> PTR <label>" possible. Masm docs also states that
PTR should have precedence 4.
- items FNRSTOR[D|W] removed from instruction table.
- some instructions, which should have accepted a word-sized memory
operand only, did accept any operand size: LLDT/SLDT, LMSW/SMSW,
LTR/STR, FLDCW/FSTCW, FNSTCW, FSTSW, VERR/VERW.
- the variants of string instructions (CMPS, INS, LODS, MOVS, OUTS,
SCAS, STOS) WITH suffix (B,D or W) didn't accept the optional (memory)
operand(s).
- the '=' directive didn't work with values enclosed in quotes.
- for COFF, the start label is now stored in the decorated form, but
without leading underscore (example: label LibEntry, language stdcall,
3 DWORD params is exported as "LibEntry@12").
- if a data item was a segment or group symbol, a wrong fixup was
generated.
- if INVOKE had to push a far address, its assumptions about what
to push as the segment part were a bit too simple.
- LABEL directive did accept near/far labels with incompatible
offset size qualifier (i.e. "near32" if current segment is 16bit).
- TR6 register wasn't accepted for cpu 80386.
- GROUP directive didn't ensure that the segment's offset magnitude
matches the group's one.
- in data items, segment/group name overrides were rejected if the
offset part wasn't a label. Example: mov ax, DGROUP:[0].
- for cpu < 80386, conditional NEAR jump was rejected, but it should
be allowed if OPTION LJMP is on (which is the default).
- if a "relocatable number" has been defined with EQU it wasn't checked
in later passes if the value did change.
- .EXIT didn't work if OS_OS2 was selected with .MODEL directive.
- syntax "TYPE offset <label>" was rejected, but should return size of
<label>'s offset (2 or 4).
- if an error was displayed, then the current line often wasn't written
to the listing file.
- the INCLUDE directive wasn't handled by the preprocessor. As a result,
if the -EP cmdline option was set to print preprocessed lines to stdout,
the content of include files wasn't contained in the output.
- the lines displayed on stdout when -EP was set wasn't just pure
assembly source, it contained generated code, the JWasm logo and
things displayed by the ECHO directive.
- if a source filename was found in the cmdline without extension, then
".asm" was added automatically, which is an error.
- OPTION PROLOGUE and OPTION EPILOGUE did verify the correctness of the
user-defined prologue/epilogue macros, which was too early.
- if the end delimiter was missing for the COMMENT directive, an
infinite loop might have occured.
- "short jump extension" didn't work if the jump to the target was far,
external and needed an operand size prefix (66h).
- type coercion for conditional near jumps (near16/near32) was ignored.
- nested procedures were rejected, but they should be allowed as long as
they don't have parameters, locals or register "uses".
- .RADIX expects its parameter in decimal, the current radix is ignored.
- if an item was defined both as PUBLIC and EXTERNDEF, but wasn't defined
in the module, an error ("Cannot define as PUBLIC...") was displayed.
Other changes:
- ALIGN(n) supported as segment attribute for COFF/ELF.
- 'characteristics' accepted as segment attributes for COFF:
INFO, READ, WRITE, EXECUTE, SHARED, NOPAGE, NOCACHE, DISCARD.
- 32bit floating-point immediate values accepted ("mov eax, 1.0").
- INCBIN directive added.
- new -Zne cmdline option to enforce strict Masm compatibility.
- PROC <prologuearg> supported, default prologue understands
FORCEFRAME and LOADDS.
- NOT and MOD operators work on 64bit operands (Masm v8 compatible).
- PARA, USE16, USE32 removed from the table of reserved words.
- "type expressions" now supported.
- clean-up of the expression evaluator's source code.
- OPTION FIELDALIGN and OPTION PROCALIGN added.
- support for alternative names in EXTERN has been added. Syntax is
EXTERN name ( altname ) :qualifiedtype
- display of include file nesting structure on errors improved.
- cmdline option -Zf added.
- the guess about a segment's type using the segment's name - which
is done if the class gives no hint - has been restricted to OMF
output format.
- warning is displayed if a text macro is used BEFORE it's defined.
- for LEA instruction, segment overrides are skipped.
- remaining hard-coded text constants moved to file msgdef.h.
- after 10000 assembly passes a warning is displayed.
- Makefile MinGW.MAK added to allow to create JWasm with MinGW.
- sample OS216.asm added.
- directives .LISTIF (.LFCOND), .NOLISTIF (.SFCOND) and .TFCOND
supported.
- directives .LISTMACRO (.XALL), .NOLISTMACRO (.SALL) and
.LISTMACROALL (.LALL) supported.
- directive .LISTALL supported.
- Cmdline options -Sa and -Sx supported.
- Cmdline options -Cu and -Cx supported.
- OPTION CASEMAP:NOTPUBLIC implemented.
- size of symbol hash table increased from 2003 to 8009. Gives a speed
boost of 10-20% for programs with lots of symbols (WinInc/Masm32).
- symbol table listing is created a lot faster.
- wildcards allowed in source filename parameter.
- the max. line length has been increased to 600 (512), the max. number
of tokens in a line is now 150 (128).
10/26/2008, v1.93:
Bugfixes:
- possible buffer overflow wasn't detected during macro expansion.
- on fatal errors there was a try to close a file twice, resulting
in an access violation.
- if there were multiple ".stack <size>" lines, the last one determined
the stack size. However, the highest <size> is to be the stack size.
- in the listing, the "current location" was displayed as segment size,
which isn't necessarily the same.
- if an 'EXTERN:varname' line occurs AFTER <varname> has been defined,
the EXTERN directive is ignored by Masm (a Masm bug?). Now JWasm
behaves similar.
- JWasm did expand macro function calls within string function parameters
later than Masm. Sometimes this was incompatible.
- some invalid numbers weren't detected.
- there was a risk that POPCONTEXT caused a nesting error if the
matching PUSHCONTEXT was done before any code bytes were emitted.
- for SHLD & SHRD, acccepted format of 3. operand was restricted.
- there was no error displayed when a 16bit segment's size exceeded
the 64k limit.
- in medium, large and huge memory models the module name, which is
used as name prefix for the default code segment, wasn't transformed
to upper case.
- in v1.90-1.92, if /Zd was set, there was a risk that the first line
number stored was 0.
- SSE3 instructions ADDSUBPD/ADDSUBPS were silently skipped if second
operand was a memory reference.
- for ELF format, type of externals was 0x0B, should be 0x0 (STT_NOTYPE).
- OPTION directive allowed one argument only. Now multiple arguments,
separated by commas, are accepted.
Other changes:
- option '-o' removed. Optionally it can be activated in the source.
- C style hex numbers with "0x" prefix no longer accepted (was an
undocumented "feature"). Optionally it can be activated in the source.
- .RADIX supported.
- for OMF, 32bit segment definition records are now used only if
necessary (segment size >= 64 kB), similar to Masm.
- Supplemental SSE3 (SSSE3) instruction set supported.
- files opcodes.tok and Bin\mkopcode.exe became obsolete and have been
removed from the source package.
09/20/2008, v1.92:
Bugfixes:
- if an assembly time variable was assigned a value which doesn't
fit in 32bits, the assignment failed.
- for some instructions a forward reference to a variable might
have caused error "invalid instruction operands".
- a '&' after (or before?) a double quote in a macro might have
confused JWasm and prevented a parameter or local to be replaced by the
current value.
- in a C expression, operators && and || weren't detected if
immediately followed by a '(' or '['.
- MOV <seg_reg>, <memory> and MOV <memory>, <seg_reg> caused
error 'invalid instruction operands' in v1.8 - v1.91 if <memory> was
a forward reference.
- the linux binaries in v1.9 and v1.91 caused a "segmentation
fault" if JWasm tried to display an error.
- offset operator didn't skip a label's type information. So
"mov eax,[esi+offset buffer]" was rejected if TYPE of buffer wasn't 4.
- for INVOKE, it was detected if EAX was overwritten, but AX
wasn't checked.
- register arguments in INVOKE weren't expanded (for 32bit code,
an 8bit or 16bit register must be expanded to 32bit; for 16bit code,
an 8bit register must be expanded to 16bit).
- due to special handling of INCLUDE and INCLUDELIB arguments macro
functions and text macros didn't work as expected after these
directives.
- OPTION EPILOGUE:NONE did translate RET to RET <nnn>.
- if the '=' directive was used to assign a relocatable value to a
variable, usage of OFFSET operator in the expression caused error
"constant expected".
- the epilogue code generated by RET wasn't parsed immediately
if the instruction was located inside a FOR|REPEAT|WHILE loop.
- the code which detected local macros wasn't safe and didn't
account for '&' operators or macro function calls before the MACRO
keyword.
- in v1.91, evaluation operator % used before a text macro name did
double the '!' if the text macro was a parameter in a string macro
function call.
- in v1.90 and v1.91, "literal concatenation" - a literal enclosed
in <> or {} is continued if last non-space character of the line
is a comma - didn't work for data initializers.
- INCLUDE directive in a FOR/REPEAT/WHILE loop didn't immediatedly
include the file's content, but waited until the loop was finished.
- if an error occured inside a macro the line number displayed was
one too high.
- if a parameter for a string function (CATSTR, SUBSTR, ...) is a
text macro id, the "evaluated" value of the existing id is to be
assigned to the new id. The "depth" of the evaluation has been
adjusted to almost match Masm, but there are still small differences.
- if a macro parameter had an invalid name, no error was displayed.
- if a macro parameter was followed by a ':', no error was displayed
if the token following wasn't '=', REQ or VARARG.
- if the rvalue of EQU contained a text equate name, the lvalue became
also a text equate. Now the rvalue is expanded and THEN tested if
it evaluates to a numeric value.
- array initializers within struct initializers had problems to
detect the end of the initialization string.
- if a literal missed the closing delimiter '>' or '}', it was always
flagged as an error, which turned out to be too restrictive.
- syntax "mov eax,4(5)" was rejected (brackets allow to omit the
'+' operator).
- in the line "ifaneb EQU .if eax != ebx" the exclamation char was
lost because the rvalue is stored as a string enclosed in <>, which
requires that '!' are doubled.
- errors which occured when the listing file was opened were ignored.
- type comparison of public data items which also had an externdef entry
was too rigid and often failed for arbitrary types.
- for INVOKE, if an address was to be pushed (ADDR operator) and the
parameter wasn't declared FAR, just the offset was pushed. Now the
segment part is also pushed if the parameter's size is @wordsize+2
(which is 4+2 in 32bit and 2+2 in 16bit).
- for INVOKE, if cpu was < 80386 and a dword-sized constant value had
to be pushed, there was a risk that the value was calculated wrong.
- simplified segment directives didn't accept segment names beginning
with a dot.
- syntax "invoke (ExitProcess)" wasn't accepted.
Other changes:
- MSVC.MAK has been adjusted to make it compatible with NMAKE v8 of
MS VC++ EE 2005. Additionally, the source has been modified: header
file windows.h is no longer used and thus the MS PSDK isn't needed
anymore.
- MAKEFILE has been adjusted to allow to create the JWasm DOS version
with native WLINK cmdline options.
- INCLUDELIB library paths are no longer added to the symbol table.
- PARITY? and OVERFLOW? supported.
- names for macro locals now consist of a "??" prefix and a hexadecimal
number suffix. Previously it was a decimal number suffix.
- fatal error displayed if writes to the object module are failing.
- WIN16.ASM sample added.
08/19/2008, v1.91:
Bugfixes:
- for /elf, section flag WRITEABLE wasn't set for .data and .bss.
- for /elf, self-relative fixups need an inline addend of -4
which was missing.
- POPAW opcode was missing and POPA was always encoded as 16bit.
- ORG outside segment block was accepted without error.
- SizeStr and InStr lines were doubled in listing.
- for INSTR, value of optional <start> parameter was ignored.
- AT was handled as a separate segment attribute, not as a
combine type value like PUBLIC or COMMON.
- address value of segment attribute AT wasn't calculated
correctly.
- there was a severe risk that the code generated by the hll
directives wasn't parsed immediately if the directive was inside a
FOR|REPEAT|WHILE loop.
- ALIGN/EVEN inside a STRUCT did set the struct's alignment
value. This isn't the way Masm does it. Now it'll adjust the offset
of the next field only.
- if "far call optimization" or "automatic jump expansion" occured
in a FOR|REPEAT|WHILE loop, wrong code might have been generated.
- in v1.9, "far call optimization" and "automatic jump expansion"
might have caused wrong code to be generated if a forward reference
was involved.
- for output formats COFF and ELF, relocateable items referencing
an assembly time variable were always fixed with the variable's final
value, which is an error.
- JWasm didn't complain if a label was reused as an assembly
time variable. Also no complains if an equate defined with the EXTERN
directive was redefined.
- symbol '$' used inside a STRUCT definition always returned 0,
but should return the struct's current offset instead.
- ORG inside a STRUCT definition didn't set the struct's
current offset.
- in a hll logical expression, just the first operand was
examined if it is a signed value, the second operand was ignored.
- a buffer overflow occured if the total size of a translated
hll expression exceeded 512.
- operands for LxS instructions weren't checked for matching
sizes.
- macro labels did work in the first macro level only. (Since
FOR, REPEAT and WHILE loops are - technically - local macros, GOTOs
didn't work within such loops if they were embedded in a macro.)
- EXITM/GOTO in a macro didn't prevent expression evaluation for
conditional assembly directives in the lines after EXITM/GOTO and
before ENDM. This might have caused message "text item required" to
appear.
- if a macro parameter was a macro function and the expansion
operator (%) was put before the macro, the expansion was skipped.
Other changes:
- TextEqu, CatStr, InStr, SizeStr, SubStr macros will now accept text
literals enclosed in <> only, to increase Masm compatibility. Literals
enclosed in quotes or {} are rejected ("text item required").
- To avoid problems with angle brackets inside literals the macro
functions @CatStr, @InStr, @SizeStr and @SubStr have been changed
to internal functions.
- Max. parameters for @CatStr() increased from 10 to 20.
- /bin cmdline parameter added.
- for INSTR/@INSTR/SUBSTR/@SUBSTR, if value of <start> parameter is
larger than size of string, an error is displayed now.
- for SUBSTR/@SUBSTR, if value of <count> parameter is too large,
an error is displayed now. Also, parameter <size> must be >= 0.
- support for .ALPHA implemented.
- REAL4, REAL8 and REAL10 will accept floating-point initializers
only.
- ALIGN will now use one-instruction no-op "lea esp,[esp+00000000]"
for a 7-byte filler in 32bit code segments.
- NDEBUG wasn't defined in release version, which caused assert()
to be active and thus bloating the binary by 5 kB.
07/24/2008, v1.9:
Bugfixes:
- a forward jump to a PROC label which wasn't reachable with
a short jump might have caused invalid code to be generated.
- for OMF, if a starting address was specified, there was
a MODEND record emitted anyway, but for 32bit segments it must
be a MODE32 record, else the highword of the address' offset
is ignored.
- if a data item contained a label offset and the item's size
was >= 4, there was a 32bit fixup record generated, no matter what
the label's segment was telling about the offset's magnitude.
- an equate with format <name> EQU <override>:[number], that
is, the value is an address without a symbol, caused an exception.
- "nested" procedures are no longer supported (actually, they
never were, but now an error is displayed).
- opcode PUSHAW was missing.
- PUSHA always generated the 16-bit form. In Masm PUSHA will
generate PUSHAW in 16-bit segments and PUSHAD in 32-bit segments.
- procedure parameters which were function pointers weren't
accepted by INVOKE.
- if a label was defined which had an associated EXTERNDEF,
the optional language specifier of the EXTERNDEF wasn't used.
- optional simple expression after .UNTILCXZ was ignored.
- if the difference of two offsets was calculated, it wasn't
ensured that the two labels are in the same segment.
- operator LROFFSET was accepted, but handled just like the
OFFSET operator.
- parameters for OPTION directive weren't expanded.
- if the RVALUE of a '=' directive wasn't a constant number,
error message "undefined symbol" was displayed. Changed to message
"constant expected".
- literal character operator ('!') wasn't handled the way Masm
does. So sometimes a '!' in a literal got "lost".
- padding a struct with bytes because of alignment didn't work
reliably.
- an undefined segment in a group wasn't flagged as error.
- || operator in .WHILE didn't work reliable.
- if a start label is emitted undecorated in /coff and its
language type is NONE, the underscore prefix must be omitted which
wasn't done.
- syntax errors in control-flow directives (.IF, .WHILE, ...)
weren't noticed sometimes.
- if an assembly error occured in a line which contained a %s
and -Fl switch was set, a GPF might have occured.
- .model parameter FARSTACK didn't set text equate @stack to
'STACK'.
- stack segment was added to DGROUP even if .model parameter
FARSTACK was set.
- changing language with <OPTION language> didn't update assembly
time variable @Interface.
Other changes:
- if instruction is RET[F] <value> and <value> is 0 (and it is not
external, it's now optimized to the one-byte short RET[F].
- EXTERNDEF's type comparison was too rigid for arbitrary types.
Now a symbol type conflict will be reported only if the base types
differ.
- type modifiers for DWORD data items containing label addresses will
now affect code generation.
- reserved words EQU2, .XMM2 and .XMM3 (all WASM specific) removed.
- error message texts no longer stored as string resources.
- there's now a JWasm binary for Linux available, distributed in a
separate package.
- speed optimisation: the second and further passes will no longer
scan the full source.
- the DOS binary jwasmd.exe now includes the HDPMI DOS extender code,
making it a stand-alone binary.
- directives ELSEIF1, ELSEIF2, .ERR1 and .ERR2 supported.
- -Zi option added (currently it's a no-op).
- better syntax check for the NAME directive to help to avoid using
this reserved name as an identifier.
- IMAGEREL and SECTIONREL operators supported for /coff.
- previous versions allowed instruction names used as labels. This
has been deactivated.
- -Zp[n] option added.
- structure fields are displayed in standard listing, not just in
symbol-table listing.
- for /coff, default library names are now enclosed in double quotes
only if the name contains a space (some linkers have problems with
the quotes).
- OPTION NOKEYWORD now works with all reserved words.
- improved syntax check for parameters of OPTION directive.
- ELF output format supported.
- OPTION NOREADONLY and OPTION NOOLDMACROS accepted (dummies).
- cmdline option -G<c|d|z> implemented.
- PUSHCONTEXT/POPCONTEXT implemented.
- level of warning 'cannot access label with segment registers' changed
from 3 to default level 2.
06/21/2008, v1.8:
Bugfixes:
- expression after .BREAK/.CONTINUE wasn't evaluated correctly
if it contained "&&" or "||" operators.
- if a userdefined prologue macro was executed, the first
line of the procedure was "lost".
- the value returned by a userdefined prologue macro function
was ignored.
- a forward reference to a segment name caused a "General
Failure" error.
- a text symbol defined with cmdline parameter -D got default
value <1> if no value was specified, which isn't what Masm does.
Now <> is assigned.
- bugfix (known bug): syntax
mov eax, [edi.<TYPE>].<Field_name>
is accepted now.
- bugfix (known bug): sometimes a superfluous type name wasn't skipped,
resulting in an error msg of "Symbol <TYPE>.<TYPE> is not defined".
- bugfix (known bug): a macro function had always to be called with
parameters enclosed in brackets, even if EXITM will return nothing.
This has been corrected.
- TYPE operator didn't accept register or type operands.
- if there were both an EXTERNDEF and a PUBLIC definition for
a symbol, a PUBDEF entry was added to the object module, even if the
symbol wasn't defined in the module.
- LENGTH operator didn't accept a structure field.
- communal variables were stored in one COMDEF record, no matter
how large this record might have grown. Now it is ensured that record
size won't exceed 1024.
- forward reference of a label in a LxS instructions failed
with error 'invalid instruction operands'.
- labels in data items were stored without optional offset.
- FLAT as a group override ("mov eax, offset FLAT:<symbol>")
was rejected.
- '%' used as COMMENT delimiter didn't work.
- alignment was ignored if the offset of a nested structure
was to be calculated.
- COMMENT directive wasn't recognized in an inactive IF block.
- an invalid optimization was triggered if a question mark was
the last of multiple items in a DUP argument (i.e. "DUP (?,?)"). As
a result, the total amount of space reserved was too short.
- in 16bit code segments, value 0xFC was used to pad 1 byte,
which is the CLD instruction. Now 0x90 (NOP) is used.
- a typecast to force JWasm to use the long format of an
instruction was ignored. Example:
cmp ax,1 ; the "short" (byte) format (83 F8 01) is used
cmp ax,word ptr 1 ; the "long" (word) format (3D 0001) is to be used
Now the typecast will make JWasm create the "long" format.
- .STARTUP created wrong code for TINY model.
- field initializer for a bit-field in a RECORD definition was
accepted, but wasn't stored.
- if a PROC parameter had no explicit type associated with it
(that is, the ":<type>" part was missing), then JWasm's behavior tended
to be hazardous due to the usage of uninitialized stack variables.
- if the fields in a RECORD didn't total exactly to 8,16 or 32,
the record wasn't shifted right.
- a label before a .ERRxx directive caused a syntax error.
- bugfix (known bug): labels in lines containing a "conditional assembly"
directive (IF, ELSE, ENDIF, ...) were ignored.
- if a memory operand was pushed/poped, there was no type check.
So memory items with sizes < WORD or > DWORD were accepted.
- stack <stacksize> reported error "constant operand expected"
if stacksize wasn't a single number.
- stacksize stored for stack segments was a 16bit value only.
- macro parameter expansion operator % might have caused a GPF
if the parameter was the last one and was intended to convert a number
to a literal.
- lines with the FOR/FORC directives were expanded. This was a
problem if the directive's first parameter was a valid text macro name.
- COMMENT delimiter wasn't detected if it was located behind
a ';'.
- if a numeric equate's magnitude exceeded 32bit, the high bits
were skipped. Now the equate will be stored as a text macro in this
case.
- there was no parameter syntax check for [ELSE]IFIDN[I],
[ELSE]IFDIF[I], [ELSE]IFB, [ELSE]IFNB.
- if a segment was open when the END directive was detected,
the segment's content was skipped, no error message was displayed.
- if a FOR parameter string contained a call of a macro function
which had more than 1 parameter, a syntax error occured.
- parameter syntax check for .ERRxx directive was missing.
- .ERRDEF and .ERRNDEF checked whether the symbol was defined
in all passes, but this can't be done in pass one due to possible
forward references.
- initialization of a structure/union embedded in another
structure might have failed if there were leading spaces before the
initialization string.
- a text macro defined with cmdline option -D must not have
contained a '-' or '/'.
- code for ALIAS didn't check whether the alias name was defined
elsewhere in the source.
- logical operators EQ, NE, LT, LE, GT, GE did accept constant
operands only, but they must also work with relocatable direct
addresses.
- there was a chance that an invalid OMF record was written
if lots of externals were defined which exceeded the max size of one
record.
- if a byte array in a structure was initialized with a string,
there were too many bytes emitted.
Other changes:
- error msg 'Too many arguments to INVOKE' displayed instead of just
'Syntax error'.
- undefined publics are now flagged as error when the PUBLIC directive
occurs in the source, not at the end of assembly pass one.
- if the expression after .WHILE is a constant value != 0, the initial
jump to test the condition is superfluous and is skipped now. Same
behavior as Masm.
- cmdline options -Wn, -w and -WX synch'ed with Masm, option -we deleted.
- added missing directives .LALL, .NOLISTMACRO and .NOLISTIF.
- source modules in subdirs WATCOM and WOMP included to the project,
so object modules in WATCOM and WOMP could be deleted.
- string resource handling switched to native Win32, WRES.LIB no longer
necessary and deleted.
- speed boost achieved (reduced number of necessary passes) by better
handling of forward references.
- GOTO supported.
- more than one source file in the command line accepted.
- directive .UNTILCXZ supported.
- operator THIS implemented.
- OPTION LANGUAGE:<language> implemented.
- OPTION SEGMENT:<segSize> implemented.
- OPTION M510/NOM510 implemented
- OPTION OLDSTRUCTS/NOOLDSTRUCTS implemented.
- OPTION SCOPED/NOSCOPED implemented.
- OPTION LJMP/NOLJMP implemented.
- OPTION EMULATOR/NOEMULATOR implemented.
- .RADIX 10 accepted (it's a noop).
- -Zm, -Sn, -nologo, -zlf, -zls options added.
- -zz option renamed to -zzp for consistency.
- -omf, -coff options added
- -bt option removed.
- -Sg, -c added (noops)
- listing is supported.
- default for floating point instructions has been changed to -FPi87,
that is, no emulator fixups are created.
- initialization for RECORD data items implemented.
- support for COFF output format implemented.
- code generated by .STARTUP is now similar to what Masm creates.
- support for segment attribute IGNORE removed.
- predefined numeric equate @WordSize added
05/20/2008, v1.7 (initial):
Changes in JWasm compared to Open Watcom's WASM v1.7.
Bugfixes:
- string equates now handled the way MASM does.
- fixup of start address now refers to the group of the start
address's segment. WASM still has problems if the
start address is in a segment which isn't the first one in a group.
- EXTERNDEFs which aren't referenced in the source now won't
cause a EXTDEF entry to be created in the object module.
- EXTERNDEFs for a symbol which were contained several times in the
source caused several PUBDEFs to be created in the object module if
the symbol was actually defined.
- SIZEOF (sometimes?) returned double the size of a variable.
- structure field names were stored in the global symbol table.
This caused various problems and often bad code was created.
- some "reserved" words in WASM, which aren't reserved in MASM
were removed from this list: "ERROR", "PRIVATE", "COMMON", "EXPORT",
"READONLY", "IGNORE", "CASEMAP", "SMALL", "MEMORY", "COMPACT", "ABS",
"NOTHING", "MEDIUM", "LARGE", "TINY", "HUGE", "USES", "FARSTACK",
"NEARSTACK", "OS_DOS", "OS_OS2".
- symbol type conflicts are now detected and reported as errors.
- default type of LOCAL variables was always WORD.
- alignment of LOCAL variables wasn't MASM-like.
- quotes and curly-bracket delimiting strings were removed during
the tokenisation process. This isn't MASM compatible.
- string equates were "evaluated" very early, making it impossible to
define a string equate which contained another string equate.
- a macro local caused a text equate with identical name to be generated
or changed. This side-effect wasn't expected.
- WASM needed ':REQ' in capitals to make a macro parameter "required".
MASM is not case sensitive here.
- macro parameters in the macro definition were expanded, which is a
bad idea. Thus it was impossible to give macro parameters a name
which was already used in the namespace (for example the name of a
previously defined macro).
- a macro name given as parameter in a IFDEF/IFNDEF line was "evaluated".
- if a source line ends with a comma, it was generally concatenated with
the next line. This caused problems with invokation of macros with
"empty" arguments. The automatic concatenation is now just done if
a text item (enclosed in <> or {}) is still open at the end of the
line and last character of the line is a comma.
- the object module to write was not always deleted if an error occured.
- arrays with 0 items caused a GPF.
- macros couldn't be redefined.
- number suffix 't' to define a decimal number) was not implemented.
- ALIAS directive syntax differed from MASM's.
- it was impossible to have a PROC with locals in a macro.
- LENGTHOF didn't work if a DB statement contained strings.
- PUBLIC + EXTERNDEF for the same label caused 2 PUBDEF records to
be written to the object module.
Other changes:
- local labels in procedures supported.
- '::' operator supported to make a label inside a procedure global.
- PROTO directive supported.
- INVOKE supported.
- TYPEDEF supported.
- UNION supported.
- RECORD supported.
- nested (and anonymous) STRUCTs and UNIONs supported.
- alignment argument for STRUCT supported.
- some MASM "options" are accepted:
+ option proc: private | public | export
+ option dotname | nodotname (nodotname is dummy)
+ option casemap:none | notpublic | all (notpublic is dummy)
+ option prologue: none | prologuedef | <macroname>
+ option epilogue: none | epiloguedef | <macroname>
+ option nokeyword: <reserved_word>
- FLAT accepted as segment attribute.
- EXTERNDEF will accept structure names as item's type.
- /Cp option added to make JWasm preserve case of identifiers.
- /zcw option added to let JWasm use the Watcom C name mangler.
(/zcm is the default now).
- LOW, HIGH, LOWWORD, HIGHWORD, OPATTR, .TYPE, TYPE, WIDTH and MASK
operators implemented.
- PROC: procedure parameters and locals are now true symbols with type
information, internally handled similiar to "structure fields".
The original approach handled these items as strings, which needs
an additional "string expansion" step inside procedures and type
information for such symbols was unavailable for the code generator.
- LOCAL directive accepts all variations which MASM does.
- LOCALs may have structured types.
- PROC parameters may have structured types.
- STRUCT "redefinitions" accepted (as long as it doesn't change the
"structure").
- numeric equates can be contained multiple times in the source as long
as their values are identical.
- macro functions and EXITM supported.
- CATSTR, SUBSTR, SIZESTR and INSTR directives supported.
- predefined macro functions @CATSTR, @SUBSTR, @SIZESTR, @INSTR supported.
- ECHO implemented.
- types REAL4, REAL8 and REAL10 supported.
- pointer qualifiers NEAR16, NEAR32, FAR16 and FAR32 supported in TYPEDEF.
- VARARG as macro parameter qualifier supported.
- .IF, .ELSE, .ELSEIF, .ENDIF, .WHILE, .ENDW, .REPEAT, .UNTIL, .BREAK
and .CONTINUE implemented.
- predefined equates @Cpu, @CurSeg, @code, @data, @stack, @Date, @Time,
@FileName supported.
- missing conditional directives (ELSEIFB, ELSEIFIDN, ...) implemented.
- evaluation operator "%" supported.
- literal character operator "!" supported.
- cmdline options made more MASM alike (-d1 changed to -Zd, ...).
- JWasm's -D cmdline option always defines a "text macro", similiar to
MASM.
- PURGE implemented.
- ASSUME <stdreg>:<ptr type> is supported.
- WHILE implemented.
- @Environ macro function supported.
- lots of debug messages added.
- type PWORD has been removed (was an alias for FWORD).
- directive DP has been removed (was an alias for DF).
- directive GLOBAL has been removed (was an alias for EXTERNDEF).
- support for JMPF/CALLF has been removed.