News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

simple conditional assembly problem

Started by Jimg, January 11, 2008, 07:53:20 PM

Previous topic - Next topic

Jimg

the following is the output listing from assembling some code-
= 00000007       C xxt1 = curmax
= 00000010       C xxt2 = maxsize
      C     if curmax gt maxsize
= 20       C         temp textequ %curmax
      C         % echo
      C         % echo ********** routine size is larger than maxsize, routine size = temp **********
      C         % echo
      C         .err       

clearly, curmax=7 and maxsize=10 hex = 16
why does the if fail?  curmax is definitely not greater than maxsize
This must be some simple thing I'm missing here, but after two hours, I just can't seem to see it.

MichaelW

By my definition of fail, the if should fail. I can't come up with any code arrangement that will produce a listing with:

= 20 C temp textequ %curmax

But the listing seems to imply that the value of curmax is 20 instead of 7. Zooba once posted a neat trick for displaying the value of a numeric equate:

http://www.masm32.com/board/index.php?topic=3909.msg29864#msg29864

eschew obfuscation

zooba

Works for me:

curmax = 7
maxsize = 10h

xxt1 = curmax
xxt2 = maxsize
if curmax gt maxsize
    temp textequ %curmax
    echo hi
endif


gives:

= 00000007         curmax = 7
= 00000010         maxsize = 10h

= 00000007         xxt1 = curmax
= 00000010         xxt2 = maxsize
                if curmax gt maxsize
                   temp textequ %curmax
                   echo hi
                endif


If I change the GT to LT, it gives this:

= 00000007         curmax = 7
= 00000010         maxsize = 10h

= 00000007         xxt1 = curmax
= 00000010         xxt2 = maxsize
               if curmax lt maxsize
= 7                temp textequ %curmax
                   echo hi
               endif


You haven't cut out any of your code there have you? Or running any macros?

Michael,

I think the C shows up when you enable timing information. These are compile-time functions, hence no timing to speak of.

Cheers,

Zooba :U

MichaelW

QuoteI think the C shows up when you enable timing information.
My test code was essentialy the same as yours, with essentially the same listing. I was not looking for a way to force the C, but the 20, or any value other than the 7 that I assigned to curmax. The C indicates that the line is from an include file.

eschew obfuscation

zooba

Quote from: MichaelW on January 12, 2008, 08:21:32 AM
QuoteI think the C shows up when you enable timing information.
My test code was essentialy the same as yours, with essentially the same listing. I was not looking for a way to force the C, but the 20, or any value other than the 7 that I assigned to curmax. The C indicates that the line is from an include file.

Ah, is that what it means.

When you said any arrangement I took it as any arrangement. :P

Cheers,

Zooba :U

Jimg

Sorry, I guess I should have included more code.  Curmax is a calculated value.  Stripped down to the smallest that causes the problem, try this:
    jmp donesetup

    maxsize = 10h
    curmax = 0
   
    chkstart=$
Routine2:
    call Dummy
    jmp @f
    chksize=$-chkstart
    if chksize gt curmax
        curmax=chksize
    endif
    org chkstart+maxsize   ; make all routines the same size
    @@:

xxt1 = curmax
xxt2 = maxsize
if curmax gt maxsize
    temp textequ %curmax
    echo hi
endif

Dummy:
    retn

donesetup:



I get this in the listing:
000003FB  EB 11       C     jmp donesetup
      C
= 00000010       C     maxsize = 10h
= 00000000       C     curmax = 0
000003FD       C     
= 000003FD       C     chkstart=$
000003FD       C Routine2:
000003FD  E8 0000000B       C     call Dummy
00000402  EB 09       C     jmp @f
00000404 = 00000007       C     chksize=$-chkstart
      C     if chksize gt curmax
= 00000007       C         curmax=chksize
      C     endif
      C     org chkstart+maxsize   ; make all routines the same size
0000040D       C     @@:
      C
= 00000007       C xxt1 = curmax
= 00000010       C xxt2 = maxsize
      C if curmax gt maxsize
= 20       C     temp textequ %curmax
      C     echo hi
      C endif
      C
0000040D       C Dummy:
0000040D  C3       C     retn
      C
0000040E       C donesetup:


even though 7 is not greater than 10, it includes the code in the if.  A clue may be that "temp textequ %curmax" shows 20 as the value???

MichaelW

In my test at entry to the if statement curmax is 20.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    jmp donesetup

    maxsize = 10h
    curmax = 0
   
    chkstart=$
  Routine2:
    call Dummy
    jmp @f
    chksize=$-chkstart
    if chksize gt curmax
        curmax=chksize
    endif
    org chkstart+maxsize   ; make all routines the same size
    @@:

    xxt1 = curmax
    xxt2 = maxsize

    %echo @CatStr(curmax = %curmax)
    %echo @CatStr(maxsize = %maxsize)

    if curmax gt maxsize
      temp textequ %curmax
      echo hi
    endif

  Dummy:

    retn

  donesetup:

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Assembling: C:\masm32\My\_TRY\if.asm
curmax = 20
maxsize = 16
hi
eschew obfuscation

Jimg

Yes, I agree that that's what it is inside the if, but just before  it's 7 as it shows in the xxt1=curmax statement in the listing and indeed what it should be?   There's just no way 20 should ever appear as far as I can see.  How can the textequ change a 7 into a 20?

After more tests, it's value is clearly both 7 and 20 depending upon how you use it.  Is this some kind of quantum trick?

= 00000007       C xxt1 = curmax
= 00000005       C xxt2 = 5
= 0000000C       C xxt3 = xxt1 + xxt2
= 00000003       C xxt4 = xxt3-9
      C repeat xxt4
      C nop
      C endm
000003F6  90      1C nop
000003F7  90      1C nop
000003F8  90      1C nop
000003F9  90      1C nop
000003FA  90      1C nop
000003FB  90      1C nop
000003FC  90      1C nop
000003FD  90      1C nop
000003FE  90      1C nop
000003FF  90      1C nop
00000400  90      1C nop
00000401  90      1C nop
00000402  90      1C nop
00000403  90      1C nop
00000404  90      1C nop
00000405  90      1C nop
      C if curmax gt maxsize

MichaelW

curmax goes from 0 to 20 in the if chksize gt curmax:

    %echo @CatStr(chksize = %chksize)
    if chksize gt curmax
        %echo @CatStr(*curmax = %curmax)
        curmax=chksize
        %echo @CatStr(curmax* = %curmax)
    endif
    %echo @CatStr(curmax = %curmax)


chksize = 20
*curmax = 0
curmax* = 20
curmax = 20

These values seem logically correct, I don't know where the 7 is coming from. In my code xxt1 goes from undefined (0) to 20 when it is defined.
eschew obfuscation

Jimg

= 000003E6       C   
= 000003E6       C     chkstart=$
000003E6       C Routine2:
000003E6  E8 0000000B       C     call Dummy
000003EB  EB 09               C     jmp @f
000003ED = 00000007       C     chksize=$-chkstart
      C     if chksize gt curmax
= 00000007       C         curmax=chksize
      C     endif

there's 7 bytes between chkstart and where chksize is set. 
chkstart = 03E6h
$=03EDh
03EDh-03E6h = 7
It shows that it is 7 bytes.  Then, any time I use it in a computation, it is 7, and then half the time it magically turns into 20 when I use it in an if, or try to print it out, or use it in a repeat.  Clearly there is something I'm not understanding here.  I can't see anywhere that a 20 should come from, so I'm totally mystified.

zooba

Rather than a quantum trick, my guess is that there's some sort of delayed evaluation going on here.

I can't make it work. The value is fine, but converting it to a string breaks it. Using ALIGN, ORG or NOP instead of the call and jmp statements allows it to work, but adding other commands makes the conversion give rubbish. Each jump or call adds 10, while other commands appear to add the number of bytes making up that command.

This seems to be a compiler/preprocessor bug to me. I can't find any other reason. (I also can't figure out why the number is converted to a string to be compared to another number...)

Time to look for a workaround? ALIGN 16 will do exactly the same as your code should, as long as you want maxsize to be a power of 2. Otherwise I'm sure we can come up with another approach.

Cheers,

Zooba :U

Jimg

Thanks Zooba.  I already have a workaround, I just didn't want this to bite me some time in the future, if there was something simple I just wasn't understanding.