News:

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

Turning an integer value into a real bool

Started by Kyoy, June 06, 2005, 12:57:06 PM

Previous topic - Next topic

Kyoy

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?

brixton

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
If you love somebody, set them free.
If they return, they were always yours. If they don't, they never were..

Mirno

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

raymond

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
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

chep

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

Mirno

cmovXX does not support immediate.


mov edx, 1
test eax, eax
cmovnz eax, edx


Mirno

chep

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

QvasiModo

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

Kyoy

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 !

AeroASM

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.

sluggy

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.


roticv

Or you can do something like


test eax, eax
setz al
movzx eax, al

Tedd

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
No snowflake in an avalanche feels responsible.