if and while are jumps
A branch compares two registers and jumps to a label if the test holds: beq (equal), bne, blt, bge, plus handy forms like bgt, ble, beqz. j label always jumps. Loops are a branch at the top and a jump back at the bottom.
# sum_to(a0 = n) -> a0 = 1 + 2 + ... + n sum_to: li t0, 0 # total li t1, 1 # i loop: bgt t1, a0, done # stop when i > n add t0, t0, t1 addi t1, t1, 1 j loop done: mv a0, t0 ret
Inverting the condition
Every if, while, for and switch you've ever written ends up as branches like these.
High-level code says *when to run* a block; assembly says *when to skip* it. if (x > 0) { body } becomes "if x ≤ 0, jump past the body". The same goes for loops: while (i <= n) becomes "if i > n, jump to the end". Inverting conditions feels odd at first, then becomes automatic.
# if (a0 > 0) a0 = a0 * 2; blez a0, skip # x <= 0? skip the body slli a0, a0, 1 # body: double it skip: ret