News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

MASM 14.0 .if signed comparison bug

Started by Queue, August 04, 2017, 08:51:53 AM

Previous topic - Next topic

Queue

Just documenting an .if statement bug in MASM 14.0.23026 and newer. Conditional jumps besides jz/jnz generated from signed comparisons are short by one and end up trashing the resulting code if not accommodated.

COMMENT ~ ASM EXE
#
# ERRATA.ASM
#
# MASM Source - MASM Errata - version 1.0.0.0
#
# Noted differences between MASM versions, some causing problems.
#
# [WH]
#
# (C) All Rights Reserved
#~========================================================================================

include \masm32\include\masm32rt.inc

; int 3 align
align_int3 macro _:REQ
local $$, $$$
$$ equ $
align _
$$$ equ $ - $$
if $$$
org $$
db $$$ dup(0CCh)
endif
endm

; else align
align_else macro _:REQ
local $$, $$$
$$ equ $
align 16
$$$ equ $ - $$
if $$$
org $$
db -($$$ mod 16 lt _) * (16 + $$$ - _) dup(0CCh)
db (($$$ mod 16 lt _) + 1) * ($$$ - _) dup(0CCh)
endif
endm

; nop align
align_code macro _:REQ
local $$, $$$
$$ equ $
align _
$$$ equ $ - $$
if $$$
org $$
db -($$$ mod 4 ge 3) dup(66h)
db -($$$ mod 4 ge 2) dup(66h)
db -($$$ mod 4 ge 1) dup(90h)
dd $$$ / 4 dup(90666666h)
endif
endm

;~========================================================================================

.code

align_int3 16
db @CatStr(<!">,%@Version,<!">),0

align_else 5
EntryPoint textequ @CatStr(<EntryPoint>,%@Version)
call EntryPoint

;~........................................................................................

align_int3 16
EntryPoint proc <forceframe> uses ebx esi edi
local wRegisterLocal:WORD
int 3
align_code 16

; MASM ge 1400 jumps 1 byte short on signed comparisons (jz and jnz work)
.if sbyte ptr al >= "`"
sub al, 20h
.endif
.if sword ptr ax < "``"
sub al, 20h
.endif
.if sdword ptr eax <= "````"
sub al, 20h
.endif

align_code 16

; MASM ge 800 encoding change
cmp al, ah

align_code 16

; MASM lt 800 add unnecessary data size prefix to register mov
push ecx
mov [esp], ss
mov word ptr [esp], ss
mov wRegisterLocal, ss
pop ecx

align_code 16
ret
EntryPoint endp

;~........................................................................................

align_int3 16

end EntryPoint;*/

One potential workaround is to insert a nop before the .endif:

.if sbyte ptr al >= "a"
sub al, 20h
if @Version ge 1400
nop
endif;compat
.endif

(The nop gets consumed by the bug leaving only intended code.)

Note that the following works correctly:

.if sbyte ptr al & "a"
sub al, 20h
.endif
.if !(sbyte ptr al & "a")
sub al, 20h
.endif
.if sbyte ptr al == "a"
sub al, 20h
.endif
.if sbyte ptr al != "a"
sub al, 20h
.endif

This issue affects:
14.0.23026
14.0.23506
14.0.23918
14.0.24210
14.0.24218
14.10.25017
It doesn't affect:
12.0.40629 or older

Those are what I've checked personally, not sure if other builds in the 14.0 or 14.10 versions exist.

Queue

hutch--

I have noticed that M$ have phuked up ML.EXE with the error messages which are now as buggy as ML64. Looks like the M$ script kiddies have got at it at last.  :icon13:

K_F

Is there such a thing as Masm 14.0  :icon_exclaim:
'Sire, Sire!... the peasants are Revolting !!!'
'Yes, they are.. aren't they....'

Queue

MASM 12.0 is part of Visual Studio 2013.
MASM 14.0 is part of Visual Studio 2015.
MASM 14.10 is part of Visual Studio 2017 (though one of those version numbers for 14.0 I listed I also got out of Visual Studio 2017, and I think I recall seeing other executables with a version number of 15, so not sure why 14.10 for MASM).

Personally, I usually just use MASM 6.15, but I keep a large set of different MASM versions to double check for code compatibility issues and it helps me spot bugs like this one. If I was stuck on a desert island I'd probably opt for MASM 7.1 since it doesn't need an external err file but still only has kernel32 as a dependency. Considering how often I use SEH I should probably migrate to it and start using SafeSEH anyway.

hutch, in what way is it effing up error messages? I've only used 14 on already known assemble-able code so haven't seen error messages. 14's certainly looking screwed up enough that I'll probably just write it off as a waste of space, like all the basically broken 64-bit builds of ml.exe.

Queue

jj2007

Here is a little overview what is available. UAsm64 is my favourite, it's twice as fast as ML* and reliable.

hutch--

I have always been amused by these comparisons, since the last boxed version, MASM has been industrial software to screw mnemonics together into object modules, any pretence of it being soft friendly consumer software went out the door with ML 6.14 onwards. The ideology of the 1990s was to make everything soft, friendly, easy and usable by morons but MASM escaped this because Microsoft needed it for components of their operating system.

Without having to hold the hot little hand of the timid, MASM in both 32 and 64 bit does the job for people who actually know how to write assembler code but it has never been compromised as soft consumer software. While I have been pleased to see habran/John and nidud developing working assemblers, trying for a backdoor C compiler is simply a mistake that is wasting their work and delaying the output of a finished assembler. I eventually went to 64 bit MASM because it could be used in my lifetime. Both Watcom based assemblers need to get their core assembler up and working as release versions instead of wasting their working time on stray high level ideas.

What are my views on the flood of criticism of MASM, who cares when MASM is finished, made by Microsoft, reliable and working application ready. I have heard all of this bullsh*t before, first the TASM brigade, then years of Betov and a pile of arse kissing cronies and while all of the opposition have bit the dust, MASM is still with us, 2017 versions in both 32 and 64 bit so we know who has the runs on the board and both are at least as unfriendly as they have ever been.  :P

I should add to this, the only other stayer is the GNU AS (GAS) which is a very good tool as long as you avoid that disgusting AT&T notation. GAS is so low level you can hear the pushes and pop happening below it but it is capable of producing very good code if the programmer know how to write it. FASM deserves a mention as well, Tomas has produce a very good assembler that is highly reliable and capable of producing very high quality code, my only problem with it is it uses old style TASM notation that drives me nutz.

Queue

I'm slightly confused, when did the topic shift to assembler comparisons? On the suggestion of uasm64? I just wanted to document some MASM bugs (and ideally workarounds) and changes in generated machine code between versions. I badmouthed MASM 14 because the type of bug is pretty bad, but it's not like they can't fix it someday (and it's not like I can't either avoid the bug, workaround it, or use a different version of MASM).

Queue

jj2007

Quote from: hutch-- on August 05, 2017, 12:36:24 PMI have been pleased to see habran/John and nidud developing working assemblers

Me too, they are doing an excellent job :t

Quoteit uses old style TASM notation that drives me nutz.

That's harmless! The latest 64-bit "assemblers" by M$ force you to use...

    .if wParam == 1
      .if lParam {} 3 || pMsg {} WM_COMMAND
        .if wParam } 1 || wParam { 4
          conout "  ----------------------------------------",lf
          conout "  Ain't Vasily's runtime comparisons great",lf
          conout "  ----------------------------------------",lf
        .endif
      .endif
    .endif


...if you want modern-style runtime comparison (back on topic :bgrin:).

Shudder :dazzled:

LiaoMi

Quote from: Queue on August 05, 2017, 12:58:14 PM
I'm slightly confused, when did the topic shift to assembler comparisons? On the suggestion of uasm64? I just wanted to document some MASM bugs (and ideally workarounds) and changes in generated machine code between versions. I badmouthed MASM 14 because the type of bug is pretty bad, but it's not like they can't fix it someday (and it's not like I can't either avoid the bug, workaround it, or use a different version of MASM).

Queue

Hi Queue,

did you report this discovery to Microsoft?

jj2007

Reporting won't help. As Hutch correctly wrote, Microsoft does not want it to be user-friendly, so they ignore all user requests. Btw keep away also from this version (which I renamed, of course):

*** Assemble using \masm32\bin\ml64_14_slow /c /Zp8 tmp_file.asm ***
Assembling: tmp_file.asm
** 64-bit assembly **
...
Microsoft (R) Macro Assembler (x64) Version 14.00.24210.0
...
***  build all took 15479 ms  ***


The source is this:include \Masm32\MasmBasic\Res\JBasic.inc
Init
  MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK
EndOfCode


UAsm64 needs 300 milliseconds to do the job. The good news is YES, it does assemble correctly with ML64 - kudos to Microsoft :eusa_clap:

The bad news is if you insert, for example, a line like bug somewhere, the error messages are garbled:

\Masm32\MasmBasic\Res\JBasic.inc(47)d size
\Masm32\MasmBasic\Res\JBasic.inc(47) : error A2008:syntax \Masm32\MasmBasic\Res\JBasic.inc(48)d size


You can have more fun with Macro Assembler (x64) Version 14.10.24930.0 of 21 Feb 2017. Test it, it's great! Not compatible with anything (work in progress), but it's the latest greatest Microsoft Macro Assembler :t

P.S.: Don't miss the unofficial change list

TWell

Error message from x86 version of Microsoft (R) Macro Assembler (x64) Version 14.10.25017.0 was not trashed.
Avoid Hostx64 version.

So it just take time to fix bugs at MS, they have to learn that ml64 first  :P
Their focus is to change the CRT in every version.

hutch--

 :biggrin:

> conout "  Ain't Vasily's runtime comparisons great",lf

But sad to say for the whiners, it works just fine and even sadder, MASM has been going strong since 1982. If I wanted a C compiler I would use CL.EXE, when I want an assembler, I want something that screws mnemonics together and if its a MACRO assembler, all the better.

If you are trying to be a purist in assembler, why are the rest trying to ape MASM notation with built in .IF, INVOKE etc ...., when Microsoft only put it there in the first place for a consumer boxed version. I own the last boxed version complete and it was a 16 bit version. That is how old the design is. Like it or lump it, MASM is by far the most widely used Windows assembler and for good reason, it been around for 35 years, what about the rest.

With a MACRO assembler, simple notation for hacky API code is reasonably straight forward to write, it does not need to be a pseudo C compiler to do crap like,

invoke MessageBox,hWin,"How D, Awl","Grittings",MB_OK

If you need someone to hold your hot little hand, try something else, MASM already can produce minimal 64 bit code size, with /LARGEADDRESSAWARE can manage all of the memory in a 64 bit Windows box, AVX2, code as fast as you can write it, full include file and library files and can routinely handle as much memory as the box has available and it is here now today.

None the less I have heard all of this crap before. Japheth started JWASM back in about 2008, never finished it, dumped it and a number of forks have gushed forth out of it. I hope habran/John and nidud get their versions running as release versions in my lifetime but it is not looking like its going to happen any time soon and MASM is here now and works just fine.  :badgrin:

Queue

Quote from: LiaoMi on August 05, 2017, 06:03:40 PM
did you report this discovery to Microsoft?
No, I haven't. I don't even know where I could report this sort of information to Microsoft.

Quote from: jj2007 on August 05, 2017, 06:21:25 PM
***  build all took 15479 ms  ***
P.S.: Don't miss the unofficial change list
Like TWell said, that's most likely due to using a 64-bit build. The 64-bit builds of ml.exe also take 10+ seconds and choke on a define in MASM32's windows.inc.

There have been 64-bit builds of ml64.exe since MASM 8.0 and 64-bit builds of ml.exe since MASM 12.0 (at least), and none of the 64-bit builds of ml.exe are any good (they all take 10+ seconds to assemble something that takes less than a second with the 32-bit build, and some versions just crash). I don't know of the state of the 64-bit builds of ml64.exe, but the 32-bit builds should all be good.

That bytepointer site is what prompted me to keep a collection of MASM versions to begin with. :t

Queue

hutch--

Queue,

The version of ML64 to use in VC2017 is in the x86_amd64 directory at 402,584 bytes. The other works but is really slow to get going.

avcaballero

JWasm is said not for beginners, as it were a characteristic more. Personally, I don't have time to fight against a compiler, I'd expect that the compiler would make my life easier, not the opposite.

I respect the hard work and disinterested around the world, but at least in my case it would be good to have a masm alternative package ready to use, unpack and run, with examples with batch files to compile in one click. Easy to use, easy to see. With no external dependencies. I think that in such case masm would desappear and jWasm an forks would reign as real successors. Alink would be an open source linker to take in account for that, for example. Nevertheless, as I said before, I respect the work that is very good, and everyone can focus their life to where they want, so, nothing to say :t.

In the other hand nasmx and fasm are very good and ready to use. The main difference with masm is that they don't use "offset" or "addr". If you want to get an addres you use "mov eax, var", if you want to take its value you use "mov eax, [var]".

goasm is a very good ready to use packet too. Maybe I miss some more examples in 64 bits.