.data
input: .asciiz "Enter limit for the sum of natural number = "
show: .asciiz " \n sum of natural numbers are = "
.text
main:
#get the integer input from user
li $v0, 4
la $a0, input
syscall
li $v0, 5
syscall
move $s5, $v0
li $v0, 1
move $a0, $s5
syscall
addi $t5, $t5, 0
iteration:
blt $t5, $s5, increment
j end
increment:
add $s2, $s2, $t5
addi $t5, $t5, 1
j iteration
end:
li $v0, 4
la $a0, show
syscall
li $v0, 1
move $a0, $s2
syscall
Ok, so I know how to take sum of n natural numbers by user input with Branch instruction but my question is: "How do I execute that same program without using Branch instructions (bge, bltv bne etc.)"
When there is a formula to compute something, as is the case with the specific problem statement in question, that's generally the best approach.
However, if you are looking more broadly for conditional execution without using classic conditional branch instructions, you can have it using unconditional branch through register instructions, with MIPS, the jr <reg>
, jump register.
Background: the conditional branch instructions test a condition and either branch or fall through to the next instruction — that is to say, there is a choice of two destinations (for the subsequently executing instruction stream) that is made dynamically.
While a jump through register will always change the flow of control and never "fall through", by definition, a jump through register can set any number of different destinations, by computing one (of several) prior to that instruction.
The simple way to look at it is to compute the following:
done := i < N
whereToGo := (&doneLabel * done) + (&LoopTop * !done)
First, a boolean is computed, whose value is either 1 or 0. In the above whereToGo
computation, only one of the two terms will be non-zero, using multiplicative identity, 1, in one case and the null factor, 0, in the other case.
(Let's note that in MIPS the <
operation to form a boolean is done with slt
and similar, and in particular, without use of conditional branch instructions.)
Here's a larger example, using a loop:
... // loop initialization
loopTop:
<do something>
done := i < N
<reg> := (&doneLabel * done) + (&LoopTop * !done)
jr <reg>
doneLabel:
...
For those who wish to avoid multiplication to accomplish this, we can use the AND
instead. To use an AND
operation, we need not a boolean 1 vs. 0, but an altered boolean -1 vs. 0. For AND
, -1 is the identity and 0 is the null factor.
done := i < N // produces 1 or 0 result (for true, false, resp.)
mask := done - 1 // produces 0 or -1 result
whereToGo := (&doneLabel & ~mask) | (&LoopTop & notDone)
In the above, mask
will be will be 0 when done
is true (and we want to exit, so we use ~mask
on that term), while it will be -1 when done is false.
Since one term will always be 0, then addition, +
vs. OR, |
are equivalent.
This approach can be generalized with more terms to choose between more destinations, of course, as long as only one term's boolean evaluates to identity and all the others are null.