I have been looking at some simple C code and the different output from GCC using different optimization levels.C code#include <stdio.h>int main() {    int i = 0;    while(i<10) {            printf(Hello\n);            i++;    }    i = 0;    while(i<10) {            printf(i: %d\n, i);            i++;    }}When I compile the code using -Os or -O2 the first loop works a bit differently. It it decrements instead of incrementing, and it is in two different ways. I am wondering why it decrements instead of incrementing like in the code, and the the small difference between -Os and -O2.-Os compiled0x400486 <main+6>       mov     edi,0x40068c0x40048b <main+11>      call    0x400450 <puts@plt>0x400490 <main+16>      dec     ebx0x400492 <main+18>      jne     0x400486 <main+6>-O2 compiled0x400490 <main+16>      mov    edi,0x40069c0x400495 <main+21>      call   0x400450 <puts@plt>0x40049a <main+26>      sub    ebx,0x10x40049d <main+29>      jne    0x400490 <main+16> 
GCC Loop optimization
disassembly
By decrementing, compiler can make use of jne (jump if not equal/zero) which does the comparison (to zero) and jump in a single instruction. In case of incrementing, it would have to do a cmp/test (with 10) and then a conditional jump like jnz/jne. I believe it is a part of optimization.-Os flag optimizes to bring down the code size. The code generated using -Os uses dec ebx instead of sub ebx, 0x1, since dec ebx is a 2-byte instruction while sub ebx, 0x1 is a 3-byte instruction (Note the address at which the next instruction begins). That explains the small difference.