News:

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

Main Menu

odd result using equ

Started by jimg, February 12, 2018, 03:41:48 PM

Previous topic - Next topic

jimg

The following code produces the wrong value in the message box for the last element-

.nolist
.386
.model flat, stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc

includelib user32.lib
includelib kernel32.lib
.list
.data
MsgCaption db "equtest",0
.data?
    dbuf db 1000 dup (?)
    hx dd ?
    wr RECT <?>
    wx equ wr.left
.code

Program:
    mov hx,8888
    mov wr.left,10
    mov wr.right,90
    mov wr.top,20
    .data
    dbgfmt db 'hx=%d',10
        db 'wr.left=%d',10
        db 'hx=%d',10
        db 'wx left=%d',10
        db 'hx=%d',10
        db 0
    .code
    invoke wsprintf,addr dbuf,addr dbgfmt, \
       hx,wr.left,hx,wx,hx
   
invoke MessageBox, 0,addr dbuf, addr MsgCaption, MB_OK
invoke ExitProcess,0
end Program


Once I display the equated value, wx, the following value (the third print of hx) prints out wr.top instead.

I tried an old version of jwasm, which also produced the incorrect value.

Masm 6.14 and 6.15 work correctly.

jj2007

Apparently a problem of all Watcom forks: JWasm version 29 Nov 2012 shows the bug already.

The problem sits here, in user32.inc: wsprintfA PROTO C :VARARG

Masm32 str$() works fine in the Watcom forks:  mov eax, wx
  print str$(eax), 9, "wx", 13, 10 ; str$(wx) chokes!
  print str$(hx), 9, "hx", 13, 10
  print str$(wr.left), 9, "wr.left", 13, 10
  print str$(wr.right), 9, "wr.right", 13, 10
  print str$(wr.top), 9, "wr.top", 13, 10


MasmBasic seems not affected: The only occurrence of a C: VARARG proto concerns MakePath, e.g. in \Masm32\MasmBasic\Res\SkelGuiPaths.asc, and that works just fine. But then, MakePath is a macro that pushes paras manually, i.e. it doesn't use invoke at all.

So it seems that invoke is the culprit, for C VARARG PROTOs only. We'll see what the UAsm team will find 8)

  int 3
  invoke wsprintf,addr dbuf,addr dbgfmt, hx,wr.left,hx, wx, hx


UAsm64
00401066             .  CC                 int3
00401067            Ú.  FF35 40954000      push dword ptr [hx]
0040106D            ³.  FF35 54914000      push dword ptr [409154]
00401073            ³.  FF35 50914000      push dword ptr [409150]
00401079            ³.  FF35 4C914000      push dword ptr [40914C]            ; Ú<%d> = 20.
0040107F            ³.  FF35 48914000      push dword ptr [wr]                ; ³<%d> = 10.
00401085            ³.  FF35 40954000      push dword ptr [hx]                ; ³<%d> = 8888.
0040108B            ³.  FF35 48914000      push dword ptr [wr]                ; ³<%d> = 10.
00401091            ³.  FF35 40954000      push dword ptr [hx]                ; ³<%d> = 8888.
00401097            ³.  68 08804000        push offset dbgfmt                 ; ³Format = "hx=%d",LF,"wr.left=%d",LF,"hx=%d",LF,"wx left=%d",LF,"hx=%d",LF,""
0040109C            ³.  68 58914000        push offset dbuf                   ; ³Buf
004010A1            ³.  E8 20000000        call wsprintfA                     ; ÀUSER32.wsprintfA
004010A6            ³.  83C4 28            add esp, 28


MLv615
00401066             .  CC                 int3
00401067            Ú.  FF35 40954000      push dword ptr [409540]            ; Ú<%d> = 8888.
0040106D            ³.  FF35 48914000      push dword ptr [409148]            ; ³<%d> = 10.
00401073            ³.  FF35 40954000      push dword ptr [409540]            ; ³<%d> = 8888.
00401079            ³.  FF35 48914000      push dword ptr [409148]            ; ³<%d> = 10.
0040107F            ³.  FF35 40954000      push dword ptr [409540]            ; ³<%d> = 8888.
00401085            ³.  68 08804000        push offset 00408008               ; ³Format = "hx=%d",LF,"wr.left=%d",LF,"hx=%d",LF,"wx left=%d",LF,"hx=%d",LF,""
0040108A            ³.  68 58914000        push offset 00409158               ; ³Buf
0040108F            ³.  E8 20000000        call wsprintfA                     ; ÀUSER32.wsprintfA
00401094            ³.  83C4 1C            add esp, 1C

johnsa


Will have a look see :) busy working on a smallish update at the moment anyway, if i can squeeze a fix in for this it'll be included.

jimg

John-

Did you get a chance to look at this?

I only ask because I know how these things can fall in the cracks when you're busy doing other fun stuff ;)

johnsa

It's on my radar :) I've been swamped the last week or two with 9-5 stuff.. which is landing up to be more like 9-10pm stuff haha... big project release this week...

jimg

No problem, just checking.  I vaguely recall the situation you're describing back in 2002 :)

johnsa

Ok,

So it seems the problem isn't really the invoke itself it's how the EQU is handled..
If I change it to wx TEXTEQU <wr.left> then we get:



00401000  mov         dword ptr ds:[40341Ch],22B8h 
0040100A  mov         dword ptr ds:[403420h],0Ah 
00401014  mov         dword ptr ds:[403428h],5Ah 
0040101E  mov         dword ptr ds:[403424h],14h 

00401028  push        dword ptr ds:[40341Ch]  8888
0040102E  push        dword ptr ds:[403420h]  10
00401034  push        dword ptr ds:[40341Ch]  8888
0040103A  push        dword ptr ds:[403420h]  10
00401040  push        dword ptr ds:[40341Ch]  8888
00401046  push        403008h 
0040104B  push        403034h 
00401050  call        00401078



Which is correct.

So it would seem that the EQU is interpreting that reference as an offset from struct base.. so when it gets to the invoke it sees a type and uses it's total size of 16bytes to generate the pushes.
We could change this, but it may break other things.. alternatively the above works with textequ ? (which should also work in masm)
Let me know your thoughts.

jj2007

Quote from: johnsa on March 26, 2018, 11:23:50 PMWe could change this, but it may break other things..

If the new behaviour is identical to the behaviour of ML.exe, then the risk of breaking old code is pretty low IMHO.

jimg

It's always a problem deciding which masm bugs to duplicate and which to fix.
If I am interpreting the programmers guide correctly (see below) then
   masm did the correct thing, but it shouldn't have.
   uasm did the wrong thing and shouldn't have.
I don't know for sure which is better/worse, but I suspect masm is better in this case.
I think both should have issued an error.
For uasm to issue an error now would probably break a lot of code, but is still the correct thing to do.
For uasm to push the entire structure when only a single element is desired is clearly an error to me.

As an aside, I am always amazed when, after 26 years, I learn something new about masm.
I never knew you could just put the name of a structured variable (in this case wr) and have every element of the structure pushed.

From page 12 of the Masm 6.1 programmers's guide:
symbol EQU expression
The symbol is a unique name of your choice, except for words reserved by MASM. The expression can
be an integer, a constant expression, a one- or two-character string constant (four-character on the
80386/486), or an expression that evaluates to an address.

In the line
    wx equ wr.left
is "wr.left" any of those things?

If so, it should have worked.
If not, it should have issued an error.
In no case that I can think of should usam have pushed the whole structure.


johnsa

It wasn't so much that it was pushing the whole structure it was a series of unfortunate events :)
It evaluated wr.left to mean an addr+offset combination.. then later it tried to get the size of the qualified type, which pointing at the structure returned 16 bytes.. thus multiple pushes were issued.

In some case MASM simply ignores what comes after the EQU if it is not sure and treats it as a text macro.. so this is what I've done now for .10
If the item after the EQU is a type and proceeded by a DOT (.) then I'll assume the reference should be maintained as textual until it can be evaluated correctly.

It fixes your case you posted and hasn't broken any of my other test pieces or the regression suite.. so give it a try :)

John

jimg

It worked!

Thanks much for you efforts an patience :)

johnsa

Thanks for your patience.. took me a while to get around to finishing up this .10 release! :)


jj2007

Quote from: david12 on June 30, 2018, 02:31:26 AM
tried it, didnt work for me.
thanks anyway

But you managed to place a link to the sillygate site, congrats :t
(beware of the cleaning squad, though :greensml:)

jimg

Quote from: johnsa on March 27, 2018, 01:41:00 AM
Thanks for your patience.. took me a while to get around to finishing up this .10 release! :)
Thanks John.  I look forward to testing it out.  I assume it will be available on the terraspace soon.

johnsa

2.46.10 which contains this fix is on the site for windows. 2.47 will be ready in the next few days for all platforms which contains this fix plus a number of others.

Cheers
John