x64 Assembly Tutorial 19: FLAGS Register, Conditional Jumps and Moves
In this, the 19th, tutorial we're going to be looking at the FLAGs register. We will only cover the general purpose programming flags here but there's many more for system programming and debugging. The Flags register is a collection of bits which describe the results of previous instructions. For instance, if you subtract a register from another and end up with zero, the Zero flag will become 1. If you add 1 to a byte which has 255 in it, the Carry flag will be set. You can use the bits in the Flags register to conditionally jump to labels with the conditional jumps. Sometimes you'll see the conditional jumps collectively written as Jcc. For instance JNZ means jump to the label only if the Zero flag is not set. JZ means jump only if the Zero flag is a 1. There are many conditional jumps but these ones and those from tutorial 8 I think cover almost all of them. In addition to having a conditional jump for most of these flags there are also conditional moves, sometimes written as CMOVcc. They begin with CMOV, for conditional move. After the CMOV you have the same letters as are present in the corresponding Jumps. If the condition being tested is true, the source operand (Op2) is moved into the destination (Op1) otherwise the destination is left untouched. The conditional moves are very important in optimization. If you can it will almost always be quicker to replace the following: cmp ebx, eax jne DontSet mov ecx, ebx DontSet: With a much faster conditional move: cmp ebx, eax ; Set the flags register cmovne ecx, ebx ; Move ebx into ecx if ebx != eax The conditional moves remove any chance of the CPU mispredicting a branch by removing the branch. Also, I've neglected to mention but we really shoudn't assume our CPU can do conditional moves, we should be calling CPUID first, more on this later.
In this, the 19th, tutorial we're going to be looking at the FLAGs register. We will only cover the general purpose programming flags here but there's many more for system programming and debugging. The Flags register is a collection of bits which describe the results of previous instructions. For instance, if you subtract a register from another and end up with zero, the Zero flag will become 1. If you add 1 to a byte which has 255 in it, the Carry flag will be set. You can use the bits in the Flags register to conditionally jump to labels with the conditional jumps. Sometimes you'll see the conditional jumps collectively written as Jcc. For instance JNZ means jump to the label only if the Zero flag is not set. JZ means jump only if the Zero flag is a 1. There are many conditional jumps but these ones and those from tutorial 8 I think cover almost all of them. In addition to having a conditional jump for most of these flags there are also conditional moves, sometimes written as CMOVcc. They begin with CMOV, for conditional move. After the CMOV you have the same letters as are present in the corresponding Jumps. If the condition being tested is true, the source operand (Op2) is moved into the destination (Op1) otherwise the destination is left untouched. The conditional moves are very important in optimization. If you can it will almost always be quicker to replace the following: cmp ebx, eax jne DontSet mov ecx, ebx DontSet: With a much faster conditional move: cmp ebx, eax ; Set the flags register cmovne ecx, ebx ; Move ebx into ecx if ebx != eax The conditional moves remove any chance of the CPU mispredicting a branch by removing the branch. Also, I've neglected to mention but we really shoudn't assume our CPU can do conditional moves, we should be calling CPUID first, more on this later.