In order to use a conditional jump a condition must be tested. Testing a condition here refers only to the act of checking the flags, the actual jumping is described under Conditional jumps.
x86 tests conditions by relying on the EFLAGS register, which holds a set of flags that each instruction can potentially set.
Arithmetic instructions, like
add, and logical instructions, like
and, obviously "set the flags". This means that the flags CF, OF, SF, ZF, AF, PF are modified by those instructions. Any instruction is allowed to modify the flags though, for example
cmpxchg modifies the ZF.
Always check the instruction reference to know which flags are modified by a specific instruction.
x86 has a set of conditional jumps, referred to earlier, that jump if and only if some flags are set or some are clear or both.
Arithmetic and logical operations are very useful in setting the flags. For example after a
sub eax, ebx, for now holding unsigned values, we have:
|Flag||When set||When clear|
|ZF||When result is zero.|
EAX - EBX = 0 ⇒ EAX = EBX
|When result is not zero.|
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
|CF||When result did need carry for the MSb.|
EAX - EBX < 0 ⇒ EAX < EBX
|When result did not need carry for the MSb.|
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
|SF||When result MSb is set.||When result MSb is not set.|
|OF||When a signed overflow occurred.||When a signed overflow did not occur.|
|PF||When the number of bits set in least significant byte of result is even.||When the number of bits set in least significant byte of result is odd.|
|AF||When the lower BCD digit generated a carry.|
It is bit 4 carry.
|When the lower BCD digit did not generate a carry.|
It is bit 4 carry.
and instructions modify their destination operand and would require two extra copies (save and restore) to keep the destination unmodified.
To perform a non-destructive test there are the instructions
They are identical to their destructive counterpart except the result of the operation is discarded, and only the flags are saved.
test eax, eax ;and eax, eax ;ZF = 1 iff EAX is zero test eax, 03h ;and eax, 03h ;ZF = 1 if both bit[1:0] are clear ;ZF = 0 if at least one of bit[1:0] is set cmp eax, 241d ;sub eax, 241d ;ZF = 1 iff EAX is 241 ;CF = 1 iff EAX < 241
The CPU gives no special meaning to register values1, sign is a programmer construct. There is no difference when testing signed and unsigned values. The processor computes enough flags to test the usual arithmetic relationships (equal, less than, greater than, etc.) both if the operands were to be considered signed and unsigned.
1 Though it has some instructions that make sense only with specific formats, like two's complement. This is to make the code more efficient as implementing the algorithm in software would require a lot of code.