Consider the code block:
int x = 0;
while(x <= 10) {
x++;
}
x += 4;
while(x > 10) {
x--;
}
x -= 4;
When we have a loop condition that involves a non-zero argument, we need to re-express that condition in terms of a zero argument. The code block above translates to:
int x = 0;
while(x -10 <= 0) { // or [ 0 <= 10 - x]
x++;
}
x += 4;
while(x -10 > 0) { // or [ 0 > 10 - x]
x--;
}
x -= 4;
Converting to assembly gives:
0: ld $0x0000, r0 # x = 0
# first loop, false conditional at top
2: ld $0xfffffff6, r1 # r1 = -10
8: mov r0, r2
add r1, r2 # r2 = x - 10
bgt r2, 0x0012 # if x-10 > 0, x > 10, !(x <= 10) goto +3
inc r0 # x++
br 0x0008 # goto -4
12: add $4, r0 # x += 4
# second loop, true conditional at bottom
14: ld $0xfffffff6, r1 # r1 = -10
1a: br 0x0022 # goto +4
1c: dec r0 # x--;
mov r0, r2
add r1, r2 # r2 = x - 10;
22: bgt r2, 0x001c # if x-10 > 0, x > 10 goto -3
add $-4, r0 # x -= 4
Note: the condition being evaluated in each case is identical, it is just treated differently. In one block, it is used as a condition to exit the loop; in the other, it is used as a condition to continue the loop.