For example (on a hypothetical RISC without optimization), total = 0; for(i = 0; i < 5; i=i+1) total = total + 1; total = 0; for(i = 0; i < 5; i=i+1) total = total + 1; So
mov r0, #0 // r0: total = 0 mov r1, #5 mov LP_COUNT, r1 // loop counter (special register) mov r1, #0 // r1: i = 0 lp L1 // add r0, r0, #1 // begin_of_loop: total = total + 1 add r1, r1, #1 // i = i + 1 L1: // if --LP_COUNT != 0 goto begin_of_loop ... // first command after loop
and if(counter > 10) then counter = 0 else counter = counter + 1
// r0: counter cmp r0, #10 bgt L1 // counter > 10 add r0, r0, #1 // else counter = counter + 1 b L2 L1: sub r0, r0, r0 // then counter = 0 L2:
And in some ISA (Instruction Set Architecture) there can be such "exotic"
cmp r0, #10 movgt r0, #0 // if counter > 10 counter = 0 addle r0, r0, #1 // if counter <= 10 counter = counter + 1
with a "dense" stream of commands without transitions (suffixes define conditional execution, the command will be executed according to the current state of the NZVC flags, which was generated in this case by the previous cmp command)
mov R0, #4is exactly what a normal modern optimizing compiler will do with your first example - Mike