I was told that this will turn integer into a bool
neg eax // say if eax is 5, that will turn it into -5 which is FFFFFFFB
sbb eax,eax //it becomes FFFFFFFF
inc eax // eax becomes 0 ... how is that turning integer into a bool??
But i don't really understand why. Can someone explain please?
Hmm, I don't know anything about it, but doesn't that make sense? Isn't it just making EAX 0 if the number is negative, and 1 if it's positive? Or am I on the wrong lines? :red
From Intel's data sheet on the x86 instruction set:
Quote
IF DEST ← 0
THEN CF ← 0
ELSE CF ← 1;
FI;
DEST ← – (DEST)
So if the register is non-zero the carry flag is set.
By using sbb, you are doing a subtraction with an extra - 1 if the carry flag is set. So "sbb eax, eax" = 0 if carry is not set, and -1 (0xFFFFFFFF) if it was.
Then incrementing the result will fix the -1 to zero, and the zero to 1. So if eax was zero the result is 1, if it was non-zero the result is zero. This is the wrong way around.
To fix this replace "inc eax" with "neg eax".
Of course the traditional boolean is only a byte, and there are a host of setXX instructions to support these boolean operations.
neg eax,
setnc al
test eax, eax
setnz al
And many more.
Mirno
What is generally considered a bool is either TRUE or FALSE. A return value of zero (0) in EAX is interpreted as meaning FALSE with the Win32 API's. If it's not FALSE, any return value other than 0 in EAX is usually considered as TRUE although the Win32 equate for TRUE is the value 1.
Within your own assembly program, you are free to do whatever you wish. If you must return some success/failure code from your own procedures, use whatever value is most appropriate.
If you have a different interpretation for a "real" bool, let us know so that someone can provide a more specific answer.
Raymond
Quote from: raymond on June 06, 2005, 02:11:33 PM
If you have a different interpretation for a "real" bool, let us know so that someone can provide a more specific answer.
raymond, I guess he wants to convert an integer (which following your definition, and mine also, is already a boolean :wink) to either TRUE (1) or FALSE (0) as per the C standard.
IMHO this can be useful only when you don't want to "leak" a sensitive value.
Quote from: Mirno on June 06, 2005, 02:03:49 PM
Of course the traditional boolean is only a byte
True, but AFAIK in the Windows API booleans are represented as DWORDs.
So I'd use:
test eax, eax
cmovnz eax, 1
You could also want to use the VB convention (where TRUE = -1, another great example of MS' consistensy)...
cmovXX does not support immediate.
mov edx, 1
test eax, eax
cmovnz eax, edx
Mirno
Indeed. :red :red :red :red :red
From now on I'll maximize Acrobat Reader's window so I can read what's really written. :wink :red
Quote from: chep on June 06, 2005, 02:30:05 PM
So I'd use:
test eax, eax
cmovnz eax, 1
It should be noted that the cmov family of instructions are only present in Pentium processors and above. If backwards compatibility with 386 and 486 is a must, this snippet could be a problem.
QuoteYou could also want to use the VB convention (where TRUE = -1, another great example of MS' consistensy)...
No, that's an example of BASIC language compatibility... remember that in C we have both logical and bitwise operators, but in BASIC we only have the bitwise ones. ;)
Thanks guys, that answered my question.
Seems like
neg eax
sbb eax,eax
neg eax
is correct. But some stated that since BOOL is 32 bits in win32 that code isn't correct. Why? I don't see a difference.
Also,
mov edx, 1
test eax, eax
cmovnz eax, edx
Mirno : Do you mind explaining why that will covert an integer value into a bool?
Thanks again !
If eax = 0, then the test will set the Zero Flag and the cmovnz will not execute, leaving eax = 0 = FALSE
If eax = anything else, then the test will reset the Zero Flag and the cmovnz will execute, setting eax = 1 = TRUE.
Quote from: Kyoy on June 07, 2005, 03:50:38 AM
Seems like
neg eax
sbb eax,eax
neg eax
is correct. But some stated that since BOOL is 32 bits in win32 that code isn't correct. Why? I don't see a difference.
That code is correct. Technically a bool is any size you want to make it, after all you only need one bit to hold the value of a bool. The size of the variable used to hold a bool is determined by the language you are using. I can't remember what the ANSI C standard size is, but an educated guess would say that it is either 8 or 16 bits, whereas VB (and numerous other languages) hold it as a 32 bit sized variable.
Or you can do something like
test eax, eax
setz al
movzx eax, al
Just to confuse things even more..
You can almost always get away with not doing anything to turn it into a bool, because it already 'is' a bool.
If it's zero, then it's false; any other value means true.
However, as far as understanding that original piece of code goes:
neg eax ;eax becomes inversed, but more importantly the carry-flag is set to 0 (if eax=0), else set to 1
sbb eax,eax ;eax = eax - (eax + <carry-flag>)
;so eax is now either: -1 (if carry was 1; so eax was true) or 0 (so carry was 0, so eax was false)
neg eax ;eax turns into: 1 (if it was -1) or 0 (if it was 0)
And obviously, 1 is true, and 0 is false :toothy