Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As you wrote, x86 <code>TEST</code> operation does a bitwise <code>AND</code> operation. You should check again the truth table for AND: </p> <pre><code>INPUT OUTPUT A B A AND B 0 0 0 0 1 0 1 0 0 1 1 1 </code></pre> <p><code>TEST</code> would do this operation for each 2 corresponding bits in the src and the dst operands, so only bits that are <code>1</code> in both would become <code>1</code> in the result: <code>00001111b &amp; 00000010b</code> would simply give <code>00000010b</code>. </p> <p>The effect on the flags is now simple to see - ZF=0 since the result is non-zero, SF=0 since the result MSB is off, and CF=0 because TEST won't set it (it's a logical operation, not an arithmetic one).</p> <p>By the way, <code>TEST</code> is quite cheap as operations go, so you may notice it's used often as a simple zero check - <code>TEST RAX, RAX</code> would AND the RAX register against itself (resulting in the same value of course), so you get a nice way to check if RAX is zero (for e.g. to be used by a <code>je</code> branch immediately after), or negative (by using the SF with a <code>js</code> branch)</p> <p>Now, the other 2 questions deal with another operation - <code>CMP</code> does an actual subtraction (it's doing the same thing as <code>SUB</code>, but also discards the result, only updating the flags). </p> <ul> <li><p>The first would compute <code>00000110b - 00000101b = 00000001b</code>, with ZF=SF=0 (for the same reasons as above), and CF=0 since we didn't have any need for carry/borrow.</p></li> <li><p>The second would compute <code>00000101b - 00000111b = 11111110</code> (two's complement representation for <code>5 - 7 = -2</code>), ZF is still 0 as above, but this time you'd see SF=1 since we got a negative result so the MSB is on, and CF=1 since the calculation did a "borrow" unto the MSB.</p></li> </ul> <p>There's a bit of a fine point here regarding CF and its counterpart OF (overflow flag) - the numbers are just numbers, they don't mean signed or unsigned values until you decide to use them as such. However x86 has to maintain the correct flags for any possibility, so it basically uses CF for unsigned operations, effectively meaning that the last operation was <code>5 - 7 = 254</code> as if you "borrowed" an extra bit to the MSB (and this is what CF=1 marks here). The OF won't get set because if you consider these exact same operation as signed arithmetic, you've really done <code>5 - 7 = -2</code> which is perfectly legal and didn't overflow/underflow. </p> <p>On the other hand, an operation such as <code>127 + 127 = 254</code> would do the opposite, it won't switch the CF (because nothing bad happened if you consider this as unsigned arithmetics), but the OF will get set because if these are signed values, you've just said <code>127 + 127 = -2</code> which is obviously wrong because there was an overflow past the max signed value a byte can store (127)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload