The MASM Forum

General => The Workshop => Topic started by: 16bitPM on October 24, 2022, 02:45:51 AM

Title: TEST vs BT
Post by: 16bitPM on October 24, 2022, 02:45:51 AM
In the book "Assembly Language Step by Step" by Jeff Duntemann, on page 306, he writes the following :

QuoteHere's something important to keep in mind: TEST is only useful for finding
1 bits. If you need to identify 0 bits, you must first flip each bit to its opposite
state with the NOT instruction. NOT changes all 1 bits to 0 bits, and all 0 bits to 1
bits. Once all 0 bits are flipped to 1 bits, you can test for a 1 bit where you need
to find a 0 bit. (Sometimes it helps to map it out on paper to keep it all straight
in your head.)

And just below he dedicates an entire paragraph to "Looking for 0 Bits with BT".

So the thing is: either I don't get it or he's wrong. If I want to test any bit for 0, I just do TEST dst, bitmask. If the zero-flag is set, the tested bits are all 0. So I can definitely test for 0-bits, or did he mean something else?

Title: Re: TEST vs BT
Post by: FORTRANS on October 24, 2022, 05:49:10 AM
Hi,

   Interesting.  Not having that book, I cannot say what he meant.
But you are right, test for zero bits works the way you say it does.
And all need to be zero to return the zero flag set.

   And if you test for more that one set bit, you would have to
reverse what the quote says.  As testing for more that one set bit
would return non-zero if any bit was set.  Not just all set.  So NOT
and test for the now zeroed bits would be required.

   Right?  Or is he testing only one bit at a time?  In which case he
might want zero to be false and non-zero to be true.  (If so, ick.)

Regards,

Steve N.
Title: Re: TEST vs BT
Post by: NoCforMe on October 24, 2022, 07:06:35 AM
Wow; I can't believe I didn't even know that this instruction (BT) was available to me, all these years. I'm going to have to use it sometime.

Anyhow, I always use TEST to check for one or more 1 bits, not zero bits. For some reason I've never needed to do that. (Well, I guess I have used a NOT - TEST sequence once or twice to check for zeroes.)
Title: Re: TEST vs BT
Post by: jj2007 on October 24, 2022, 07:34:47 AM
Quote from: NoCforMe on October 24, 2022, 07:06:35 AM
Wow; I can't believe I didn't even know that this instruction (BT) was available to me

:badgrin: :badgrin: :badgrin:

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)

3       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
4       cycles for 100 * bt ax, 1
11      cycles for 100 * test al, 2

3       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
4       cycles for 100 * bt ax, 1
11      cycles for 100 * test al, 2

4       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
4       cycles for 100 * bt ax, 1
11      cycles for 100 * test al, 2

4       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
4       cycles for 100 * bt ax, 1
11      cycles for 100 * test al, 2

8       bytes for bt eax, 1
9       bytes for test eax, 2
9       bytes for bt ax, 1
6       bytes for test al, 2
Title: Re: TEST vs BT
Post by: hutch-- on October 24, 2022, 08:20:33 AM
If you bother to look up the authoritive source, the mnemonic TEST has many uses.

    test eax, eax
    jz label

    or

    test rax, rax
    jz label
Title: Re: TEST vs BT
Post by: learn64bit on October 24, 2022, 04:08:32 PM
jj,

What the "??" mean?
Title: Re: TEST vs BT
Post by: greenozon on October 24, 2022, 05:12:26 PM
also having some "??" but in different rows...


2       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
??      cycles for 100 * bt ax, 1
5       cycles for 100 * test al, 2

3       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
??      cycles for 100 * bt ax, 1
32      cycles for 100 * test al, 2

17      cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
??      cycles for 100 * bt ax, 1
2       cycles for 100 * test al, 2

3       cycles for 100 * bt eax, 1
3       cycles for 100 * test eax, 2
??      cycles for 100 * bt ax, 1
2       cycles for 100 * test al, 2

8       bytes for bt eax, 1
9       bytes for test eax, 2
9       bytes for bt ax, 1
6       bytes for test al, 2

123     = eax bt eax, 1
123     = eax test eax, 2
123     = eax bt ax, 1
123     = eax test al, 2

--- ok ---
Title: Re: TEST vs BT
Post by: hutch-- on October 24, 2022, 07:49:15 PM
My guess as I did not write the benchmark is that the timing was so low it did not register.
Title: Re: TEST vs BT
Post by: jj2007 on October 24, 2022, 08:16:43 PM
Quote from: hutch-- on October 24, 2022, 07:49:15 PM
My guess as I did not write the benchmark is that the timing was so low it did not register.

Yes, that's probably the explanation :thumbsup:
Title: Re: TEST vs BT
Post by: Mikl__ on October 25, 2022, 09:40:45 PM
If the execution time will change if replace "test dst, bitmask" by "push dst/and dst, bitmask/pop dst"?