News:

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

TEST vs CMP ...

Started by James Ladd, June 01, 2005, 09:08:58 AM

Previous topic - Next topic

James Ladd

It has been suggested to me to use TEST over CMP especially when comparing against a literal value.
for example:

    invoke GetCL, 1, addr plugin_name
    cmp eax, 1
    jne fast_server_no_plugin_name
    invoke StdOut, addr plugin_name


The code above work if I have a value specified on the command line and I use "cmp"
Change "cmp" to "test" and it doesnt work.

What am I missing ?

Rgs, striker

Mirno

cmp is a subtract only updating the flags, while test is an and with only flags being updated.
You cannot use them interchangeably.

cmp eax, 1 -> test eax, eax

You cannot however test for any literal, "test eax, 5" will return non-zero for any number with bits 0 or 2 set (1, 4, 5, 9, 12, 13 etc.).

Mirno

MichaelW

For a zero/non-zero return value test eax,eax would work OK. But for other return values, that are not bit encoded, you can't reasonably test with a bit-wise AND, whether the result is stored or not. And in using test with a constant operand you would loose the size advantage of test eax,eax, and possibly other advantages, as this:

test eax,1
jz   fast_server_no_plugin_name
cmp  eax,1
jne  fast_server_no_plugin_name

Assembles to this:

00401000 A901000000             test    eax,1
00401005 7405                   jz      loc_0040100C
00401007 83F801                 cmp     eax,1
0040100A 7500                   jnz     loc_0040100C

eschew obfuscation

James Ladd

Thanks all,
Im a lot clearer on the use of TEST now !
Good explainations too

Rgs striker

ThoughtCriminal

How about doing sub eax,1 and testing for 0?  I'm not at a computer I check that  at right now.

thomasantony

Hi,
  TEST is a good way of checking whether a bit is set or not. It is much better than using BT or similiar. I have seen programs that use AND to test for bits. ut then they have to preserve and then restore the registers. Instead you can use TEST. TEST eax,eax is only valid to chekc whether eax is 0 or not.

Thomas
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

MazeGen

Quote from: thomasantony on June 02, 2005, 07:03:13 AM
Hi,
  TEST is a good way of checking whether a bit is set or not. It is much better than using BT or similiar.

Why do you think that TEST is better than BT?
As I see it, in case I have a bit mask, use TEST, and in case I have a bit number, use BT.

Additionally, BTR, BTS and BTC instructions are very useful for working with single bits.

thomasantony

Hi,
   TEST takes only 1-2 clocks while BT and similiar takes 3-8 clocks :bdg

Thomas :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

hutch--



Quote
TEST takes only 1-2 clocks

Where did this come from, my Intel reference on PIV and similar say 0.5 clocks. Apparently pairs nicely with the other "preferred" instructions.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MazeGen

Quote from: thomasantony on June 03, 2005, 07:21:29 AM
Hi,
   TEST takes only 1-2 clocks while BT and similiar takes 3-8 clocks :bdg

Thomas :U

Hi Thomas,
you're right (according to Agner's manual), but those instructions have different behaviour: TEST is used with bit mask, BT/BTx with bit number. Say, for instance, that EAX holds a bit number and we need to test whether is that bit set in EBX. You have to ways:


BT EBX,EAX     ; in the worstest case 6 uops (latency 4 uops + additinal latency 2 uops)
JC is_set


or


MOV ECX,EAX
MOV EAX,1     ; set mask for bit 0
SHL EAX,CL    ; set mask according to the bit number
TEST EBX,EAX
JNZ is_set


I've found the latter one definitely slower (there are many dependencies between the instructions).

BT with memory destination operand is very slow, probably slower than the variant with TEST.

donkey

For a zero test on a register I generally interchange TEST and OR, but these days I tend to use TEST exclusively. As has been said here many times CMP and TEST are not interchangeable, though TEST is excellent for a quick bit test as long as the result will always resolve to zero or 1. For example to check if the low order word has a non-zero value...

TEST EAX, 0FFh
jz > ; zero value in low order WORD.
"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