News:

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

Main Menu

UASM 2.40 release

Started by habran, September 21, 2017, 06:13:02 AM

Previous topic - Next topic

habran

Hello folks,
UASM 2.40 release is out, with fixes:
   .SWITCH to allow negative and positive cases and usage of multi cases:
         .case 1, 2, 3, 4... or
         .case 1
         .case 2
         .case 3
         .case 4
   .FOR will report an error if you don't use 2 columns, this is the minimum requirement ( : : )
   
   Improved integers usage for building with different environments
   
   fixed some problem with literals in 32 bit
   
   fixed some listing issues

check it here:     
Uasm (Site) http://www.terraspace.co.uk/uasm.html
Uasm (GitHub) https://github.com/Terraspace/UASM
Cod-Father

jj2007

Works fine with my big sources but it chokes with this one (an old source that built fine years ago... mystery ::)):

include \masm32\MasmBasic\Res\MbGui.asm
.data?
MyFonts         dd 4 dup(?)
.code
  mov edi, offset MyFonts
  MakeFont stosd, Height:14, "Times New Roman"
  MakeFont stosd, Height:16
  MakeFont stosd, Height:20
  MakeFont stosd, Height:24

Event Paint
  For_ ct=0 To 3
        mov ecx, ct
        GuiTextBox ct*32+7, ct*64+7, 100, 50, Str$("This is textbox #%i ", ct+1), font MyFonts[4*ecx]
  Next
GuiEnd


The issue is admittedly exotic (and there is a workaround, see attached project):
include \masm32\include\masm32rt.inc

any macro arg
Local oa
  oa = opattr arg
  if oa eq 48
print "&arg is a register", 13, 10
  else
print "&arg is not a register", 13, 10
  endif
endm

.code
start:
  any eax
  any nop
  inkey "Hello World"
  exit

end start


This works in UAsm and ML. This doesn't:  if (opattr arg) eq 48


In short:
oa = opattr arg works with everything,
if (opattr arg) eq ... doesn't work with an "exotic" arg like nop or stosd

This is an inconsistent behaviour, btw also of Microsoft MASM. So if you decide to remain compatible, I will support your decision :lol:

IMHO if (opattr arg) should use 0 to indicate "other" if the arg doesn't fit into the immediate, mem, register etc categories, but it should never throw an error.

habran

 :dazzled:
13120: if (opattr arg) eq 48
13121:    nop
13122: else
13123:   nop
00B09838 90                   nop 
13124:   nop
00B09839 90                   nop 
13125: endif
Cod-Father

aw27

Quote
oa = opattr arg works with everything,
Does not work in ML and works in UASM for some unknown reason.   :shock:

Quote
if (opattr arg) eq ... doesn't work with an "exotic" arg like nop or stosd

Well, we can make it work in both ML and UASM, I just don't know if this is what you want:  :icon_rolleyes:

include \masm32\include\masm32rt.inc
OPTION NOKEYWORD: <nop>

any macro arg
Local oa
  ;;oa = opattr arg
  ;;if oa eq 48
  if (opattr arg)  eq 48
print "&arg is a register", 13, 10
  else
print "&arg is not a register", 13, 10
  endif
endm

.code
start:
  any eax
  any nop
  inkey "Hello World"
  exit

end start




nidud

#4
deleted

jj2007

Quote from: aw27 on September 21, 2017, 08:17:45 PM
Quote
oa = opattr arg works with everything,
Does not work in ML and works in UASM for some unknown reason.   :shock:

You are right, it works with JWasm, UAsm, AsmC but chokes with the ML versions I tested. Sorry for the wrong info.

Quote
Quoteif (opattr arg) eq ... doesn't work with an "exotic" arg like nop or stosd

Well, we can make it work in both ML and UASM, I just don't know if this is what you want:  :icon_rolleyes:

include \masm32\include\masm32rt.inc
OPTION NOKEYWORD: <nop>

Undefining keywords is not a solution. Ideally, and that is what the Watcom family does, the programmer should decide if e.g. stosd is a valid argument or not. But for the sake of compatibility with ML, the workaround ifidni <arg>, <stosd> is acceptable and perhaps preferable.

aw27

The MASM manual expressly says "You cannot use reserved words as parameter
names (...for macros) unless you disable the keyword with OPTION NOKEYWORD".  It is not exactly the same thing as using reserved words as parameters but the MASM manual is full of slightly imprecise statements.
If JWasm, UAsm, AsmC let you do that it can be one of 2 things: a bonus or a subtle bug.
I suspect it is a bug because, as you have noticed, will not be processed within the macro as expected.

Quote
the workaround ifidni <arg>, <stosd> is acceptable and perhaps preferable
Through some magic it is possible to turn a bug into a bonus then.  :exclaim:

jj2007

Quote from: aw27 on September 22, 2017, 03:22:53 AMI suspect it is a bug because, as you have noticed, will not be processed within the macro as expected.

The "long" oa = opattr arg form gets correctly processed by UAsm:include \masm32\include\masm32rt.inc

any macro arg
Local oa
  oa = opattr arg
  if oa eq 48
print chr$("&arg is a register", 13, 10)
  else
print chr$("&arg is not a register", 13, 10)
  endif
endm

.code
start:
  ; int 3
  any eax
  any nop
  exit

end start

qWord

#8
habran,

the compiler is your willing servant: turn on all warnings (I guess you are using MSVS) and watch out for C4554(!). Checking all occurrences of C4701 and C4703 might be also useful. Easy to fix: C4101 and C4189.

BTW: Just reading some minutes in hll.c (code related to your dot-for-loop) brings up two raw copy-loops where one cause buffer overflows and the other some subtle bug that produce nonexisting identifiers while removing white spaces...

EDIT: an other nice find: C4334 (x64-Build) in expreval.c

regards
MREAL macros - when you need floating point arithmetic while assembling!

habran

Hi qWORD, thanks for reporting :t
Can you please give me some details about error in .for - .endfor code? Maybe source code?

Regarding warnings, I agree with you that it is already overdue to clean it up, however, there is always something more urgent to work on :biggrin:

I'll look at that ASAP

Cod-Father

qWord

RE C4554 (precedence of operators!):
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/codegen.c#L655
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/codegen.c#L656
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/symbols.c#L822
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/symbols.c#L825
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/symbols.c#L828

C4334 (32bit shift, but 64bit probably expected):
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/expreval.c#L303

Buffer overflow for identifiers with size >= 256 (also: if-statement in loop is deadcode):
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/hll.c#L1186

Identifiers starting with any valid ID-char. other than a-z cause concatenation of tokens (e.g BYTE ptr _MyVar):
https://github.com/Terraspace/UASM/blob/76ee4d61c6a1c4c061b083ba2c8253bb5b1c11ea/hll.c#L1606

regards
MREAL macros - when you need floating point arithmetic while assembling!

LiaoMi

Hi,

using the Visual Studio PVS-Studio plugin - https://www.viva64.com/en/pvs-studio/

QuotePVS-Studio is a tool for bug detection in the source code of programs, written in C, C++ and C#. It works in Windows and Linux environment.
PVS-Studio performs static code analysis and generates a report that helps a programmer find and fix bugs. PVS-Studio performs a wide range of code checks, it is also useful to search for misprints and Copy-Paste errors. Examples of such errors: V501, V517, V522, V523, V3001.

The main value of static analysis is in its regular use, so that errors are identified and fixed at the earliest stages. There is no point in wasting 50 hours looking for a bug that could be found with static analysis. So, let's point out that again - the main idea of static analysis is not to find one hidden bug on the day before the release, but to fix dozens of bugs day by day.

The analyzer can be run at night on the server and warn about suspicious code fragments. Ideally, these errors can be detected and fixed before getting into the repository. PVS-Studio can automatically be launched immediately after the compiler for the files that have been just modified. It works in Windows and Linux.

you can find a lot of bugs, probably not all are important, here is an interesting example

V647 The value of 'int' type is assigned to the pointer of 'char' type. Consider inspecting the assignment: 'tmp = _alloca(size)'. bin.c 1813
#if PE_SUPPORT && RAWSIZE_ROUND
    if ( modinfo->sub_format == SFORMAT_PE ) {
        size = ftell( CurrFile[OBJ] );
        if ( size & ( cp.rawpagesize - 1 ) ) {
            char *tmp;
            size = cp.rawpagesize - ( size & ( cp.rawpagesize - 1 ) );
            tmp = myalloca( size );
            memset( tmp, 0, size );
            fwrite( tmp, 1, size, CurrFile[OBJ] );
        }
    }
#endif


or

V512 A call of the 'memset' function will lead to overflow of the buffer 'sym'. symbols.c 250

struct asym *SymAlloc( const char *name )
/***************************************/
{
    int len = strlen( name );
    struct asym *sym;

    sym = LclAlloc( sizeof( struct dsym ) );
    memset( sym, 0, sizeof( struct dsym ) );


or

V501 There are identical sub-expressions 'CodeInfo->token == T_VCVTPS2PD' to the left and to the right of the '||' operator. codegen.c 988

            if (CodeInfo->token == T_VMOVHPS || CodeInfo->token == T_VMOVLPS || CodeInfo->token == T_VCVTPS2PD ||
                CodeInfo->token == T_VCVTPH2PS || CodeInfo->token == T_VCVTPS2PD ||
              CodeInfo->token == T_VPMOVQB || CodeInfo->token == T_VPMOVSQB ||
              CodeInfo->token == T_VPMOVUSQB || CodeInfo->token == T_VGATHERQPS ||
              CodeInfo->token == T_VPGATHERQD || CodeInfo->token == T_VGATHERDPS){ 
                  lbyte &= ~EVEX_P1WMASK;
            }


:redface:

V547 Expression 'CodeInfo->indexreg != 0xFF' is always false. codegen.c 2004

                if (CodeInfo->vexconst){
                  tmp &= ~NOT_BIT_345;
                  tmp &= ~BIT_012;
                  tmp |= MOD_10;
                  tmp |= RM_SIB;
                  if (CodeInfo->indexreg != 0xFF){
                    c = CodeInfo->indexreg;
                    c = (c &= 0x07) << 3;
                    CodeInfo->sib |= c;
                    c = CodeInfo->basereg;
                    c &= 0x7;
                    CodeInfo->sib |= c;
                    CodeInfo->sib &= 0xf0;
                  }


These are the results for the 64 bit release, total number of suspicions - 300, high-risk - 50 messages  :idea:

habran

Thanks both of you for your support, I am sure that there is always space for improvement and optimisation
which we have been doing 24 hours a day.
I personally don't trust so much to those vizard tools because they are not able to write UASM,
however, it doesn't hurt to look twice at some warnings.

I am planning to look again through the .FOR-.ENDFOR source and optimise and rewrite some parts, I am sure there can be done some improvements and probably add some more functionality, however, that will be for the next release, as well as clearing up some warnings.

I am also grateful to you Nidud for pushing me hard to clear all bags in SWITCH - ENDSWITCH block, that was very complex job to do but rewarding when all works flawlessly.

There is still need to recheck and fix some bugs in listing.c because we are not happy how it deals with inserted code with AddLineQueue() and AddLineQueueX()

I hope John will upload soon the last fix of hll.c
Cod-Father

johnsa

Hi,

Windows x86 and x64 packages have been updated with fixes in HLL for switch/for, a bunch of the warnings have been cleaned up as per qWords excellent list :)

Cheers
John

jj2007

Works fine for all my major sources :t