The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jj2007 on July 18, 2007, 10:49:12 AM

Title: .IF eax>=0 not working as expected
Post by: jj2007 on July 18, 2007, 10:49:12 AM
Hello,

I stumbled into an odd problem and hope you can help: The .IF directive does not work as expected.
After a ".IF eax>=0" it even shows clearly that eax=-1
The context is a FindFirstFile call, which returns a negative number (-1, to be precise) if the file does NOT exist; in all other cases, eax will contain a file handle.
So I tried my luck, and ... no luck! The jl NotEx works fine, the .IF does not. It even shows me eax as -1 through a dwtoa call...

What did I wrong???
Thanks a lot, JJ

;   *** MoveFile, kill if destination present ***
   invoke FindFirstFile,File_B,ADDR wfd   ;A=SOURCE, B=DEST
   mov   ecx,OptPtr
   mov   [ecx],eax   ;give back exist (>=0: yes indeed)
   push   eax   ;save result
   invoke FindClose,eax   ;close handle, not needed
   pop   eax   ;restore eax
   cmp   eax,0
   jl   NotEx   ;jump if less (signed)

;   .IF eax>=0   ;## file exists, eax>=0: does not work properly??!! ##
;   invoke dwtoa,eax,ADDR Number   ;## shows -1 indeed...!
;   invoke MessageBox,MDLG,ADDR Title,ADDR Number,MB_OK

   .IF (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     invoke RemoveDirectory,MsgText   ;...kill the folder
   .ELSE
     invoke DeleteFile,File_B   ;...kill the file
   .ENDIF
;   .ENDIF   ;## end of test ##

NotEx:
   invoke MoveFile,File_A,File_B   ;A=SOURCE, B=DEST
Title: Re: .IF eax>=0 not working as expected
Post by: zooba on July 18, 2007, 11:12:15 AM
By default, .if (and .while and similar statements) use an unsigned comparison. You need to specify that you want a signed comparison:

.if eax >= SDWORD PTR 0
...


Cheers,

Zooba :U
Title: Re: .IF eax>=0 not working as expected
Post by: Ian_B on July 18, 2007, 08:22:08 PM
Chalk that up as another reason not to use pseudo high-level structures in MASM that rely on critical little details the unsuspecting user would never guess, instead of coding explicitly. I've NEVER been aware of that wrinkle!  :dazzled:

I'm so glad I refuse to use IF/ELSE etc. when that level of inadvertent miscoding is possible. That's absolutely terrible.  :tdown
Title: Re: .IF eax>=0 not working as expected
Post by: u on July 18, 2007, 09:56:21 PM
Ian_B, I don't see a problem. There would be a problem if the assembler was randomly choosing if the comparison is signed or unsigned :) .
Title: Re: .IF eax>=0 not working as expected
Post by: zooba on July 19, 2007, 07:51:05 AM
It's only a problem if you don't know what the assembler is doing. Once you are aware of it there's no longer a problem.

IMHO, if you're an unsuspecting user, use Java  :P

Cheers,

Zooba :U
Title: Re: .IF eax>=0 not working as expected
Post by: Ian_B on July 20, 2007, 04:31:41 AM
Yeah, I misunderstood what was happening. Of course it is comparing 0ffffffffH > 0, not negative. It's obvious when you think about it.  :red

But this is why the IF/ELSE constructs are dangerously easy to use and I'm therefore not sure they are best programming practise in Assembler. If you use that >= construct, it is obfuscating the actual results you should be testing for. Instead of having to add extra SDWORD clutter, it's better in this case to test explicitly for the single error condition (-1) with a normal CMP EAX, VAL much as jj has done (although comparing directly to -1 would be better and easier to understand/bugfix later) and then pass through on non-error results. The original IF/ELSE here creates non-Assembler style code that is less efficient and doesn't work into the bargain without a kludge.
Title: Re: .IF eax>=0 not working as expected
Post by: jj2007 on July 20, 2007, 08:32:41 AM
Thanks a lot for your help. I'll have to check all my code now :eek
Title: Re: .IF eax>=0 not working as expected
Post by: ToutEnMasm on July 20, 2007, 09:49:11 AM
Hello,

You can use a signed data in the comparison


.data
Number SDWORD 0
.code
       mov Number,eax
       .if Number >= 0   ; Number replace eax and is signed for masm
         .
         .
       .endif

Title: Re: .IF eax>=0 not working as expected
Post by: jj2007 on July 20, 2007, 01:37:04 PM
Quote from: Ian_B on July 18, 2007, 08:22:08 PMI'm so glad I refuse to use IF/ELSE etc. when that level of inadvertent miscoding is possible. That's absolutely terrible.  :tdown
Well, the IF/ELSE etc. are indeed comfortable to use; and apparently they work perfectly for

.IF eax==123

What striked me, though, is that .IF eax>=0 is by default unsigned. That condition is always true, then...

But there is also plenty of risk messing up with the "wealth" of jump instructions and flags...
Does somebody have a shorter replacement for the two jnc/jz instructions??

   add   si,dx   ;add the string len and check if we reached a 64k boundary:
   jnc   NoChg   ;jump if carry not set
   jz   NoChg   ;jump if carry set but result still zero
   .. do stuff ..   
NoChg:   
Title: Re: .IF eax>=0 not working as expected
Post by: hutch-- on July 20, 2007, 03:32:54 PM
jj,

Using the pseudo high level stuff in MASM is a matter of personal taste. Most people know how to use them but all of the old fellas know how to code them manually as well.

Like most things, know how to use it and it works fine, the block .IF notation in masm is very useful in complex messy code where jumps and labels produce nightmares.

With the choice between signed versus unsigned, unsigned default is no problem as long as you know it and if you want signed comparison as a number of our members have shown, specify the item to be compared as signed and the comparison works fine.
Title: Re: .IF eax>=0 not working as expected
Post by: GregL on July 21, 2007, 12:08:25 AM
Quote from: Ian_BBut this is why the IF/ELSE constructs are dangerously easy to use and I'm therefore not sure they are best programming practise in Assembler.

I disagree, the high-level directives work very well, if you know how to use them.

I do think one should learn how to program MASM without them though, to learn what is going on "under the hood". But there is nothing wrong with using the high-level directives.

I think anyone that is learning to use MASM should read the MASM Programmer's Guide (http://www.masm32.com/board/index.php?topic=5433.0) cover to cover, more than once. And and use it as a reference after you have learned MASM. There is information in it that isn't available anywhere else.