Something else the HC11 does, which is very common, is to use the C bit to mean ``Borrow'' for a subtract or a compare.
Put them together, and it means you do branches by somehow getting the relevant information into the condition codes (ideally as a side-effect of some other computation that was necessary anyway), and then use an appropriate branch instruction.
Here's an example: let's assume we have a pair of signed integers in
the a
and b
accumulators, and we want to end
up with the smaller of the two in the a
accumulator. We
don't care what ends up in the b
accumulator; this isn't
a swap. We can do it like this:
cba * a - b
ble noswap * branch based on results of compare
tba * copy b into a
noswap
Here's another example: we want to compute the sum of the integers
from one to b
, where b
is the integer in the
b
accumulator. We'll assume b
is non-zero.
We can do this with a loop:
clra * a = 0
loop * do {
aba * a = a + b
decb * b = b - 1
bne * } while (b != 0)
Notice that this time, we didn't explicitly do a compare. We relied
on the fact that the decb
instruction would set the
condition codes for us.
Here's a table showing the full set of branch instructions on the HC11:
Positive Form | Negative Form | ||||
---|---|---|---|---|---|
Mnemonic | Description | Boolean Expression | Mnemonic | Description | Boolean Expression |
Unconditional | |||||
bra |
Branch Always | 1 | brn |
Branch Never | 0 |
Single Condition Code | |||||
bcs |
Branch Carry Set | C = 1 | bcc |
Branch Carry Clear | C = 0 |
bmi |
Branch Minus | N = 1 | bpl |
Branch Plus | N = 0 |
bvs |
Branch oVerflow Set | V = 1 | bvc |
Branch oVerflow Clear | V = 0 |
beq |
Branch Equal (to 0) | Z = 1 | bne |
Branch Not Equal (to 0) | Z = 0 |
Signed Branches | |||||
blt |
Branch Less Than | N ^ V = 1 | bge |
Branch Greater Than or Equal | N ^ V = 0 |
ble |
Branch Less Than or Equal | (N ^ V) | Z = 1 | bgt |
Branch Greater Than | (N ^ V) | Z = 0 | Unsigned Branches |
blo |
Branch Lower | C = 1 | bhs |
Branch Greater Than or Equal | C = 0 |
bls |
Branch Less Than or Equal | C | Z = 1 | bhi |
Branch Higher | C | Z = 0 |
Notice a few things: bpl
is misnamed - it's really on
non-negative. There are two instructions in the table that appear
twice each! The brn
instruction only exists because it
was easier to build it into the instruction set than to leave it out.
It can also be useful in timing loops.