Control flow is governed by four control flags in the processor
CF - carry flag :This is set when the operation has a carry out of the last bit. It indicates an overflow if the numbers were unsigned
ZF - zero flag :The most recent operation yielded a 0
SF - sign flag :The result of the most recent operation was negative
OF - overflow flag :Set if there was two’s compliment overflow (positive or negative)
These can be set explicitly or implicitly. They are set implicitly by almost every arithmetic operation we perform. The exception is the lea function, which was meant for address computation
we can set them explicitly using:
cmp
- compare two values (essentially subtracts the first from the second)test
- ANDs the two arguments together. If they are the same, this will be a quick way to check if it is 0 or negativeC code:
int simpleConditional(int x, int y){
int result;
if (x > y){
result = x - y;
}else{
result = y - x;
}
result *= 3;
return result;
}
Assembly:
cmpl %esi, %edi
jle .L2
subl %esi, %edi
movl %edi, %esi
jmp .L3
.L2:
subl %edi, %esi
.L3:
leal (%rsi,%rsi,2), %eax
ret
C code:
int doWhile(int x, int y){
int result;
do {
result += x;
y--;
}while (y > 0);
return result;
}
Assembly:
addl %edi, %eax
subl $1, %esi
testl %esi, %esi
jg .L5
rep ret
There is a very little difference between do while and while loops. A do while loop goes: init, body, update, test, body, update, test, body, update, test, etc… A while loop goes: init, test, body, update, test, body, update, test, body, update, etc… The difference is that the while loop does a test before it starts, or to put that another way, the do while does an iteration of body and update before it starts.
There are a couple of ways that we can translate a while loop into a do while loop.
Different levels of optimization or different loops may result in one or the other of these approaches.
C code:
int whileLoop(int x, int y){
int result;
while (y > 0) {
result += x;
y--;
}
return result;
}
Assembly :
jmp .L7
.L8:
addl %edi, %eax
subl $1, %esi
.L7:
testl %esi, %esi
jg .L8
This is basically pretty syntax for the same behavior as a while loop, so it can be converted the same way.
for (init; test; update){
body;
}
init;
while(test){
body;
update;
}