Usually the program counter increments by 1 instruction. Now we wish to modify the flow of control based on certain conditions. There is a set of single bit flag registers which describe the status of a recent arithmetic operation. Whatever the conditions evaluate to, the result is updated in one of these flag registers; and based on content of these flag registers, the flow can be directed.
The FLAGS register has 16 bits, where each bit serves as the storage for the result of different conditions/operations. The successors of FLAGS is EFLAGS, which is 32 bits wide, and RFLAGS, which is 64 bits wide.
The commonly used flags are:
CF Carry flag: used to detect overflow in operations with unsigned numbersOF The Overflow Flag is set to 1 when 2’s complement signed numbers overflow: both positive overflow and negative.ZF Zero flag if the most recent operation yielded a 0, then it is set to 1. Also used in conditional branch instructions, which alter control flow based on previous instruction results.SF Sign Flag: if the most recent operation yielded a negative value, then SF is set to 1. More generally, SF takes the value of the MSB of the value yielded. Incase it is negative, it will have a 1 as its MSB, and if non-negative, then a 0.Example:
t = a+b; in C.
t evaluates lesser than unsigned interpretation of one of the operands, then CF is set 1.t becomes 0 after the addition, then ZF is set 1.t becomes negative after addition then SF is set 1.OF is set to 1 when both following conditions are fullfilled:
a and b are of the same signa and t are of different sign (talking about the sign is meaningful when we interpret t, a, b as signed 2’s complement)lea instructions won’t change any of these flags.xor there will never be any carry generated, not will there be any overflow, so CF and OF are both set to 0.CF will be the value of the bit last shifted out, but OF is set to 0.inc and dec do modify the OF (and rightly so), but not CFcmpcmp can set all these four flags. It merely subtracts the operands passed to it and on the basis of the difference updates the flags, but doesn’t update/modify the content stored at the registers/locations which were passed as operands. By difference, we mean
cmp left_op, right_op # means right_op - left_op
ZF is set to be 0. Otherwise:ZF becomes 1SF is 1 if the difference is negative, SF is 0 if the difference in positive. It is still possible for difference to be negative when the first number is greater than the second. This because of overflow.OF is set to 1 if there is an overflow, otherwise 0.CF is set to 1 if there is a carry. Why these flags are necessary, will be revealed in the following parts of text.set family of instructionsset familyYou just ran an instruction for comparing two operands and and you need to check the result. i.e. if one of the operands is $>, \geq, <, \leq, =, \neq$ the other operand. Or maybe if the instruction gave a negative output. D is a 1 byte location in memory, or a 1 byte register %al or %bh etc.
sete D will set all 8 bits of D the same as ZFsetne D will set all 8 bits as NOT of ZFThe following instructions interpret the bits to be in 2’s complement form
setg D sets D as 1 if right_op > left_op. Works by (~(SF ^ OF)) & (~ZF)setle D should work as (SF ^ OF) | ZFsetl D works as (SF ^ OF)setge D should work as ~(SF ^ OF)Example: consider two 3 bit numbers, b which has 100 and a which is 010. Interpreting them as signed, b is -4, and a is 2. So we should get a true for b <= a and b < a.
Doing b - a which is adding 100 and 110 we get 010, and 1 as an overflow. Now,
ZF = 0SF = 0OF = 1
(SF ^ OF) | ZF is (0 ^ 1) | 0 which is 1.(SF ^ OF) is (0 ^ 1)which is 1.We can interpret 100 and 010 as unsigned and draw a similar analogy. Here the CF will be 0.
jmpjmp mylabel will jump to mylabel unconditionallyjmp *operand will jump to the address which (content at operand) bytes ahead of the current instructionje, jne, js, jg, etc. which work the same as set, except they update the program counter to the operand if the conditions evaluate to be true.Two common encodings: Relative, where jmp is given how many bytes to skip to the next instruction, the other is absolute, which gives jmp a 4 byte long absolute address.