NCL 104: Choosing a Path
In NCL 103, we made the NCS/e count down from 5:
MOVE r0 5
D.TXT "Counting: "
$again
D.TXT r0
D.TXT " "
DEC r0
BGT $again r0 0
D.BLT
The program displays:
Counting: 5 4 3 2 1
But what if we want it to count all the way down to 0?
Including zero
Let's look at the end of the loop.
After displaying 1, this instruction:
DEC r0
changes r0 to 0.
Then:
BGT $again r0 0
asks:
Is
0greater than0?
It isn't, so the branch does not happen. The CPU continues to D.BLT, and 0 is never displayed.
We need to ask a slightly different question.
Instead of BGT, we can use BGE:
BGE $again r0 0
BGE means branch if greater than or equal to.
Our program becomes:
MOVE r0 5
D.TXT "Counting: "
$again
D.TXT r0
D.TXT " "
DEC r0
BGE $again r0 0
D.BLT
Now consider what happens near the end.
When r0 contains 1, the program displays it and DEC changes it to 0.
Then:
BGE $again r0 0
asks:
Is
0greater than or equal to0?
Yes.
The CPU goes back to $again, and 0 is displayed.
DEC then changes r0 to -1.
This time, the branch asks:
Is
-1greater than or equal to0?
No.
The loop ends.
The program now displays:
Counting: 5 4 3 2 1 0
The difference between BGT and BGE is small, but important:
BGT greater than
BGE greater than or equal to
Counting the other way
We've made the NCS/e count downward.
Let's turn the loop around and count upward instead.
We can start at 1:
MOVE r0 1
Instead of subtracting 1 each time with:
DEC r0
we can add 1 with:
INC r0
Now we need the loop to continue while r0 is less than 5.
For that, NCL provides BLT.
BLT means branch if less than.
Our loop becomes:
MOVE r0 1
D.TXT "Counting: "
$again
D.TXT r0
D.TXT " "
INC r0
BLT $again r0 5
D.BLT
Walk through the changing value of r0.
It begins at 1.
The program displays 1, then INC changes r0 to 2.
Is 2 less than 5?
Yes, so the CPU goes back to $again.
The program continues with 2, then 3, then 4.
After displaying 4, INC changes r0 to 5.
Then:
BLT $again r0 5
asks:
Is
5less than5?
No.
The branch does not happen, so the loop ends.
The program displays:
Counting: 1 2 3 4
Including five
This should look familiar.
Our countdown originally stopped before 0 because BGT did not include values equal to 0.
Our new loop stops before 5 because BLT does not include values equal to 5.
Just as BGE means greater than or equal to, NCL provides BLE for less than or equal to.
Change:
BLT $again r0 5
to:
BLE $again r0 5
The complete program is now:
MOVE r0 1
D.TXT "Counting: "
$again
D.TXT r0
D.TXT " "
INC r0
BLE $again r0 5
D.BLT
After displaying 4, INC changes r0 to 5.
Then:
BLE $again r0 5
asks:
Is
5less than or equal to5?
Yes.
The CPU goes back to $again, and 5 is displayed.
Afterward, INC changes r0 to 6.
Is 6 less than or equal to 5?
No.
The loop ends.
The program displays:
Counting: 1 2 3 4 5
We've now seen four different conditions:
BGT greater than
BGE greater than or equal to
BLT less than
BLE less than or equal to
They all work the same basic way. They compare two values and branch if the condition is true.
Checking for equality
Sometimes we don't care whether one value is greater or less than another.
We want to know whether two values are exactly equal.
NCL provides BEQ, which means branch if equal.
Consider this program:
MOVE r0 5
BEQ $five r0 5
D.TXT "The number is not five."
$five
D.TXT "The number is five."
D.BLT
The branch:
BEQ $five r0 5
asks:
Is the value in
r0equal to5?
Here, r0 does contain 5, so the CPU branches to $five.
The program displays:
The number is five.
That seems to work.
Now change:
MOVE r0 5
to:
MOVE r0 3
Before you run the program, try following it from the top.
The branch:
BEQ $five r0 5
now asks:
Is
3equal to5?
No.
The branch does not happen, so execution continues downward.
The program writes:
The number is not five.
Then the CPU reaches:
$five
A label does not stop execution. The CPU simply continues with the next instruction:
D.TXT "The number is five."
So our program displays:
The number is not five.The number is five.
That's not what we wanted.
Jumping without a condition
When the number isn't 5, we want to display:
The number is not five.
and then skip over the other message.
We don't need to ask another question to do that. We already know where execution should continue.
NCL provides JUMP for this.
MOVE r0 3
BEQ $five r0 5
D.TXT "The number is not five."
JUMP $done
$five
D.TXT "The number is five."
$done
D.BLT
Unlike the branches we've used so far, JUMP does not compare any values.
This instruction:
JUMP $done
simply means:
Continue execution from
$done.
Let's follow both possible paths.
If r0 contains 5:
BEQ $five r0 5
branches to $five.
The CPU executes:
D.TXT "The number is five."
Then execution continues downward through $done to D.BLT.
The program displays:
The number is five.
If r0 does not contain 5, the BEQ does not branch.
The CPU executes:
D.TXT "The number is not five."
Then:
JUMP $done
skips over $five and its message.
Execution continues from $done, and D.BLT makes the selected message visible.
The program now follows one of two different paths depending on the value in r0.
Branching if values are different
BEQ branches when two values are equal.
NCL also provides its opposite:
BNEQ
BNEQ means branch if not equal.
For example:
BNEQ $different r0 5
means:
If the value in
r0is not equal to5, continue execution from$different.
Just like the other branches, if the condition is false, execution simply continues with the next instruction.
Try it
Start with our program that chooses between two messages:
MOVE r0 5
BEQ $five r0 5
D.TXT "The number is not five."
JUMP $done
$five
D.TXT "The number is five."
$done
D.BLT
Try several different values in:
MOVE r0 5
Before running the program, follow it from the top and predict which message will be displayed.
Then try changing the value being compared:
BEQ $five r0 10
What else needs to change for the messages to make sense?
Finally, try changing the program to use BNEQ instead of BEQ.
Remember that changing the condition changes which path branches and which path continues downward.
Follow both paths before you run it.
In the next lesson, NCL 105: Keeping Track of More, we'll start using more than one register in the same program.