test reg, reg
(where reg
is the same for both operands) is what you'll almost always see instead of:
cmp reg, 0
in optimized code. Both instructions set the flags the same way, but the former takes fewer bytes to encode and is therefore slightly faster.
Therefore, your code just tests to see whether the esi
register is zero or not. If it is non-zero, it takes the branch; if it is zero, execution falls through without branching.
Why does this work? Well, as you seem to already know, the TEST
instruction just does a bitwise-AND on its operands. So what does the truth table say for bitwise-AND?
|===============================|
| Bit 1 | Bit 2 || AND |
|---------|---------||----------|
| 0 | 0 || 0 |
| 1 | 0 || 0 |
| 0 | 1 || 0 |
| 1 | 1 || 1 |
|===============================|
The middle two cases can be ignored, since in this special case, we know that both operands are the same value. So, when esi
is 0, TEST
will set the zero flag (ZF) to 1, because the result of the bitwise-AND is 0. And, conversely, when esi
is non-zero, TEST
will turn off the zero flag, because the result if the bitwise-AND is non-zero.