News:

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

Test eax,eax

Started by Farabi, August 05, 2008, 09:25:46 AM

Previous topic - Next topic

Farabi

What is test eax,eax mean? And what is it used for?
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Vortex

Hi Onan,

test eax,eax is used to check if eax is equal to 0. If this is the case then the ZERO flag is set to TRUE.

An example :

invoke  VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE            ; allocate memory
    test    eax,eax
    jnz     @f


If VirtualAlloc fails, it returns 0. If the value of eax is not zero then the ZERO flag is set to FALSE. This means that the code will jump to the nearest forward label.

From \masm32\help\opcodes.hlp :

QuoteTEST - Test For Bit Pattern
        Usage:  TEST    dest,src
        Modifies flags: CF OF PF SF ZF (AF undefined)
        Performs a logical AND of the two operands updating the flags
        register without saving the result.

hoverlees

TEST is Only a little different from AND.

PBrennick

Both of you gentlemen make correct points but the most important point is that, while AND is a destructive test; Test is not. This means, if you use AND, the destination is modified and the flags set accordingly. If you use TEST, the flags are modified accordingly but the destination variable (and the source) are not modified. TEST does an AND of the 2 variables but does not change them, in other words.

-- Paul
The GeneSys Project is available from:
The Repository or My crappy website

jj2007

Quote from: PBrennick on August 05, 2008, 01:29:47 PM
while AND is a destructive test; Test is not

Another non-destructive test is or eax, eax

Mark Jones

Timings may differ on the various platforms but OR EAX,EAX and TEST EAX,EAX are generally much faster than CMP EAX,0 or similar.

Likewise, if it is necessary to perform many tests, it may be even faster to use a look-up table. There should be many posts here describing how to use a lookup table (see the XLAT instruction.)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Farabi

Thanks,  I understad it now.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

raymond

Quote from: jj2007 on August 05, 2008, 03:10:18 PM
Quote from: PBrennick on August 05, 2008, 01:29:47 PM
while AND is a destructive test; Test is not

Another non-destructive test is or eax, eax

"or eax,eax" is as much a destructive test as the "and eax,eax".
They both entail writing the result to the register (even though there is no change in these cases) while test does not write to any general purpose register.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

donkey

Also remember that TEST does not only set the zero flag, it will set any of the flags for example if you need to know if the number is negative or if you use it with a constant you can check the value of a bit in eax, eg...

test EAX, 1
jnz @F ; << jump if bit 0 is set

this would be equivalent to the BT opcode, except it can check multiple bits for example TEST EAX, 6 will result in a zero flag if either bit 1 or bit 2 is not set. It is a very useful opcode and a relatively fast one.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

hutch--

TEST is a very useful mnemonic, test any bit and not change the value in the register.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc


    mov edx, 00000000000000010000000000000000b      ; set bit 17

    test edx, 00000000000000010000000000000000b     ; test bit 17
    jz notset

    print "Bit 17 is set",13,10
    jmp quit

  notset:
    print "Bit 17 is NOT set",13,10

  quit:

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: raymond on August 06, 2008, 03:05:25 AM

"or eax,eax" is as much a destructive test as the "and eax,eax".
They both entail writing the result to the register (even though there is no change in these cases) while test does not write to any general purpose register.


What is your definition of "destructive"?

Tedd

"test" does a virtual 'and' on the destination operand with the source operand, but does not write the result back.
"and" does an 'and' on the destination operand with the source operand, and writes the result back to the destination operand.
"or" does an 'or' on the destination operand with the source operand, and writes the result back to the destination operand.

(a related example is 'cmp' and 'sub' -- cmp does a virtual sub, but doesn't write the result back to the destination.)


If you "and" or "or" a value with itself, the result will be the original value (with only the flags being modified), but these instructions are 'destructive' in that they write the result back to the destination operand. They may write the exact same value back, but they still essentially destroy the previous value (it's modified, even if not changed.)



Farabi: "test eax,eax,", "and eax,eax", "or eax,eax", "cmp eax,0" are all just ways of checking if eax == 0. They don't change the value in eax, but if the result of the operation is 0, then the zero-flag is set.
If you 'and' a number with itself, you will get the same number as the result, and the zero-flag will be set if the result of an operation (i.e. that number) is zero. And the same for if you 'or' a number with itself.
"cmp" also works the same -- if you subtract 0 from a number, the result will be the same, and the zero-flag will be set if that result is zero (which must mean the original number was zero: 0 - 0 = 0).
No snowflake in an avalanche feels responsible.

jj2007

Ok, what you write is technically and philosophically correct, but let me put it more bluntly: Does it matter? Will the CPU police put me in jail if I destroy the valuable contents of eax with or eax, eax? Will the OS police hit me over the head if I insert a mov esi, esi in my callback procedure although I forgot uses esi?

raymond

QuoteWill the OS police hit me over the head if I insert a mov esi, esi in my callback procedure although I forgot uses esi?

This has nothing to do with the fact that "or" is destructive.

(BTW, I very often use the esi, edi, ebx (and even the ebp if I need it) registers without saving them IF they don't need to be saved. :clap:)
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Tedd

Quote from: jj2007 on August 06, 2008, 11:55:00 AM
Ok, what you write is technically and philosophically correct, but let me put it more bluntly: Does it matter?
Obviously, no - not really.
However, one could argue that's it's more efficient, since writing back a value requires an extra micro-op that could really be skipped otherwise.

Quote
Will the CPU police put me in jail if I destroy the valuable contents of eax with or eax, eax? Will the OS police hit me over the head if I insert a mov esi, esi in my callback procedure although I forgot uses esi?
We can always hope, my friend :bdg
No snowflake in an avalanche feels responsible.