4. Control Flow
So far, our programs have been boring (we figured out how to use a calculator, yay), let's make them more interesting with loops, and control flow. All control flow is done with branches and jumps.
_main_loop:
# clear screen
# draw one thing
# sleep
# eat
# draw another thing because why not
j _main_loop # j stands for jump, this is an infinite loop
Convention
Start labels with _ unless they are functions or variables. Labels are a memory address to a place in memory.
Conditional Branches
Instruction | Meaning |
---|---|
beq a, b, label |
if (a == b) { goto label } |
bne a, b, label |
if (a != b) { goto label } |
a
must be a register, b
can be a register or immediate.
Danger
WHEN WRITING LOOPS, WRITE PSEUDOCODE AND IGNORE THE INSIDE STUFF. TRANSLATE THE CONTROL FLOW TO ASM FIRST!!!!!!!!!!!!!!!!!!!!
Jumping
In Java/C you jump over a condition when it is FALSE
In ASM, you jump over a condition when it is TRUE
# if (s0 == 30) {
# block A
# } else {
# block B
# }
# block C
bne s0, 30, _blockB
# block A
j _blockC
_blockB:
# block B
_blockC:
# block C
More branch instructions
Instruction | Meaning |
---|---|
bltz a, label |
if(a < 0) { goto label } |
blez a, label |
if(a <= 0) { goto label } |
bgtz a, label |
if(a > 0) { goto label } |
bgez a, label |
if(a >= 0) { goto label } |
Also,
Instruction | Meaning |
---|---|
slt c, a, b |
if(a < b) { c = 1 } else { c = 0 } |
Set if Less Than: register c will be set to 1 if $a < b$, otherwise register c will be set to 0. Using slt with bne and beq we can inplement all conditionals: $a=b$, $a\neq b$, $a > b$ $a \geq b$, $a < b$, and $a \leq b$.
Or just use the pseudo-instructions,
Instruction | Meaning |
---|---|
blt a, b, label | if(a < b) { goto label } |
ble a, b, label | if(a <= b) { goto label } |
bgt a, b, label | if(a > b) { goto label } |
bge a, b, label | if(a >= b) { goto label } |
$a$ must be a register, but $b$ can be a register or immediate.
Complex Conditions
To use ands:
To use ors:
# if (s0 == 30 || s1 > 1) {
# block A
# }
bne s0, 30, _blockA
ble s1, 1, _skipA
_blockA:
# block A
_skipA:
Loops
Loops are similar to conditionals, we want to leave the loop when the opposite of what ever the condition is.
# for(int i = 0; i < 10; i++) {
# print(i);
# }
li s0, 0
_loop_top:
bge s0, 10, _carry_on
move a0, s0
li v0, 1
syscall
addi s0, s0, 1
j _loop_top
_carry_on:
# more code
# while(s2 < 10) {
# stuff
# }
# more stuff
_loop_top:
bge s2, 10, _more_stuff
_stuff:
# stuff
j _loop_top
_more_stuff:
# more stuff
Wait, don't forget about continue and breaks!