X86 Assembly/Control Flow

Almost all programming languages have the ability to change the order in which statements are evaluated, and assembly is no exception. The instruction pointer (EIP) register contains the address of the next instruction to be executed. To change the flow of control, the programmer must be able to modify the value of EIP. This is where control flow functions come in.

Comparison Instructions
Performs a bit-wise logical  on   and   the result of which we will refer to as   and sets the  (zero),  (sign) and   (parity) flags based on. is then discarded.

 Operands 

reference accumulator
 * Register
 * Immediate
 * Register (where  can be encoded specially if   is an immediate value)
 * Memory

 Modified flags 


 * ≔ MostSignificantBit
 * ≔ ( = 0), so a set   means,   and   do not have any set bits in common
 * ≔ BitWiseXorNor( [Max-1:0]), so  is set if and only if  [Max-1:0] has an even number of 1 bits
 * ≔ 0
 * ≔ 0
 * is undefined

 Application 


 * passing the same register twice:
 * becomes the sign of, which is a simple test for non-negativity
 * is set if  is zero
 * is set if  has an even number of set bits

Performs a comparison operation between  and. The comparison is performed by a (signed) subtraction of  from , the results of which can be called. is then discarded. If  is an immediate value it will be sign extended to the length of. The  register is set in the same manner as a   instruction.

Note that the GAS/AT&T syntax can be rather confusing, as for example  followed by   will branch if   (and not the opposite as might be expected from the order of the operands).

 Operands 

minuend subtrahend
 * (only if  is immediate)
 * Register
 * Memory
 * Register
 * Immediate
 * Memory

 Modified flags 


 * ≔ MostSignificantBit, so an unset  means the   is non-negative (  ≥   [NB: signed comparison])
 * ≔ ( = 0)
 * ≔ BitWiseXorNor( [Max-1:0])
 * ,  and

Jump Instructions
The jump instructions allow the programmer to (indirectly) set the value of the EIP register. The location passed as the argument is usually a label. The first instruction executed after the jump is the instruction immediately following the label. All of the jump instructions, with the exception of, are conditional jumps, meaning that program flow is diverted only if a condition is true. These instructions are often used after a comparison instruction (see above), but since many other instructions set flags, this order is not required.

See chapter “X86 architecture”, § “EFLAGS register” for more information about the flags and their meaning.

Unconditional Jumps
Loads  with the specified address (i.e. the next instruction executed will be the one specified by  ).

Jump if Equal
ZF = 1

Loads  with the specified address, if operands of previous   instruction are equal. is identical to. For example:

Jump if Not Equal
ZF = 0

Loads  with the specified address, if operands of previous   instruction are not equal. is identical to

Jump if Greater
SF = OF and ZF = 0

Loads  with the specified address, if the   of the previous   instruction is greater than the second (performs signed comparison).

Jump if Greater or Equal
SF = OF or ZF = 1

Loads  with the specified address, if the   of the of previous   instruction is greater than or equal to the   (performs signed comparison).

Jump if Above (unsigned comparison)
CF = 0 and ZF = 0

Loads  with the specified address, if the   of the previous   instruction is greater than the. is the same as, except that it performs an unsigned comparison.

That means, the following piece of code always jumps (unless  is , too), because negative one is represented as all bits set in the two's complement. Interpreting all bits set (without treating any bit as the sign) has the value 2ⁿ-1 (where n is the length of the register). That is the largest unsigned value a register can hold.

Jump if Above or Equal (unsigned comparison)
CF = 0 or ZF = 1

Loads  with the specified address, if the   of previous   instruction is greater than or equal to the. is the same as, except that it performs an unsigned comparison.

Jump if Lesser
The criterion required for a  is that   ≠ . It loads  with the specified address, if the criterion is met. So either  or   can be set, but not both in order to satisfy this criterion. If we take the  (which is basically what a   does) instruction as an example, we have:



With respect to  and   there are several cases that fulfill this criterion:


 * 1)   <   and the operation does not have overflow
 * 2)   >   and the operation has an overflow

In the first case  will be set but not   and in second case   will be set but not   since the overflow will reset the most significant bit to zero and thus preventing   being set. The  ≠   criterion avoids the cases where:


 * 1)   >   and the operation does not have overflow
 * 2)   <   and the operation has an overflow

In the first case neither  nor   are set, in the second case   will be set and   will be set since the overflow will reset the most significant bit to one and in the last case neither   nor   will be set.

Jump if Less or Equal
≠  or.

Loads  with the specified address, if the   of previous   instruction is lesser than or equal to the. See the  section for a more detailed description of the criteria.

Jump if Below (unsigned comparison)
CF = 1

Loads EIP with the specified address, if first operand of previous CMP instruction is lesser than the second. is the same as, except that it performs an unsigned comparison.

Jump if Below or Equal (unsigned comparison)
CF = 1 or ZF = 1

Loads  with the specified address, if   of previous   instruction is lesser than or equal to the. is the same as, except that it performs an unsigned comparison.

Jump if Zero
ZF = 1

Loads  with the specified address, if the zero bit is set from a previous arithmetic expression. is identical to.

Jump if Not Zero
ZF = 0

Loads  with the specified address, if the zero bit is not set from a previous arithmetic expression. is identical to.

Jump if Signed
SF = 1

Loads  with the specified address, if the sign bit is set from a previous arithmetic expression.

Jump if Not Signed
SF = 0

Loads  with the specified address, if the sign bit is not set from a previous arithmetic expression.

Jump if Carry
CF = 1

Loads  with the specified address, if the carry bit is set from a previous arithmetic expression.

Jump if Not Carry
CF = 0

Loads  with the specified address, if the carry bit is not set from a previous arithmetic expression.

Jump if Overflow
OF = 1

Loads  with the specified address, if the overflow bit is set on a previous arithmetic expression.

Jump if Not Overflow
OF = 0

Loads  with the specified address, if the overflow bit is not set on a previous arithmetic expression.

Jump if counter register is zero
CX = 0

ECX = 0

RCX = 0

Loads  with the specified address if the counter register is zero.

Application

 * The existence of this instruction makes the counter register particularly suitable for holding (high-level language) pointers: In most programming languages the “null pointer”, an invalid pointer, is implemented by the numeric value . Usually, you do not want to dereference such a null pointer as the result will be bogus or even cause a GPF. By jumping away, with , to some code handling this error, you can avoid running into such a situation before you attempt to dereference the pointer value. You do not need an extra.
 * If you are using the  instruction to implement a loop, but it is possible the requested number of iteration is zero, you may want to insert a   before the loop’s body. Otherwise,   will decrement zero, thus ending up doing 232 iterations.

Function Calls
Pushes the address of the instruction that follows the  call, i.e. usually the next line in your source code, onto the top of the stack, and then jumps to the specified location. This is used mostly for subroutines.

Pops the next value on the stack into, and then pops the specified number of bytes off the stack. If  is not supplied, the instruction will not pop any values off the stack after returning.

Loop Instructions
The  instruction decrements   and jumps to the address specified by   unless decrementing   caused its value to become zero. For example:

does not set any flags.

These loop instructions decrement  and jump to the address specified by   if their condition is satisfied (that is, a specific flag is set), unless decrementing   caused its value to become zero.


 * loop if equal
 * loop if not equal
 * loop if not zero
 * loop if zero

That way, only testing for a non-zero  can be combined with testing. Other flags can not be tested for, say there is no  “loop while   ≠ 0 and   unset”.

Enter and Leave
creates a stack frame with the specified amount of space allocated on the stack.

destroys the current stack frame, and restores the previous frame. Using Intel syntax this is equivalent to:

This will set  and   to their respective value before the function prologue began therefore reversing any modification to the stack that took place during the prologue.

Other Control Instructions
Halts the processor. Execution will be resumed after processing next hardware interrupt, unless  is cleared.

No operation. This instruction doesn't do anything, but wastes (an) instruction cycle(s) in the processor.

This instruction is often represented as an  operation with the operands   and   (an operation without side-effects), because there is no designated opcode for doing nothing. This just as a passing remark, so that you do not get confused with disassembled code.

Asserts #LOCK prefix on next instruction.

Waits for the FPU to finish its last calculation.

Programmation Assembleur x86/Les branchements