News:

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

.IF eax>=0 not working as expected

Started by jj2007, July 18, 2007, 10:49:12 AM

Previous topic - Next topic

jj2007

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

zooba

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

Ian_B

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

u

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 :) .
Please use a smaller graphic in your signature.

zooba

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

Ian_B

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.

jj2007

Thanks a lot for your help. I'll have to check all my code now :eek

ToutEnMasm

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


jj2007

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:   

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

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 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.