The HC11 has a pretty rich set of arithmetic instructions, intended for doing eight-bit arithmetic on the A and B accumulators. It can also combine the A and B accumulators into a single, 16 bit D accumulator. In this first section, we'll only be discussing the eight bit accumulators.
There are a few things to notice about how these instructions are structured.
First, there are typically both "general" and "specific"
forms of the instructions; for instance, you can add an arbitrary
eight bit constant to an accumulator or you can increment the
accumulator by one. Normally, the general form will do anything you
need (you can certainly add one to the A accumulator with an
adda
instruction instead of saying inca
),
but the specific form will save time, space, or both (in this case, it
will save one byte of memory), so it is used to optimize the code.
Second, a computer with a single register to "accumulate" its results, and which uses this register as the implicit destination of all its arithmetic instructions, is called an "accumulator" or "one-address" machine, and its single register is called the "accumulator." It's called a one-address machine because one address (in this case, a memory location) is specified in every arithmetic instruction.
A machine with several registers, any of which can be the destination of an arithmetic instruction, is called a "two-address" machine since instructions specify two addresses (the address of a register, and the address of a memory location) with every arithmetic instruction (Intel uses a two-address instruction, and is also more flexibile in that the result can be stored in either the register or the memory address specified in the instruction).
The HC11 is somewhere intermediate between being an accumulator machine and a two-address machine, since it has two registers for arithmetic. Most of the time, it's regarded as being an enhanced accumulator machine, rather than a restricted two-address machine, and its arithmetic registers are called accumulators.
We can set an accumulator to a known value with a clra
,
clrb
, ldaa
, or ldab
instruction.
As the names imply, the clra
and
clrb
instructions set the values of the A or B
accumulator to 0. These instructions do not take an argument. They
set the condition codes as you'd expect: N=1, the others are all 0.
The ldaa
and ldab
instructions set the
accumulator to an arbitrary eight bit value. They take the form
lda
r arg
where r is either a
or b
(as
appropriate), and arg is the argument. They set the N and Z
bits appropriately, clear the V bit, and (surprisingly) leave the C
bit unchanged. This last is to help with multiple-precision
arithmetic later on.
The arithmetic operations are adda
, addb
,
suba
, and subb
. All take a single operand
(like ldaa
and ldab
), and all set all the
condition codes appropriately. A little bit of a surprise in how the
subtract instructions set the condition codes is that, instead of
using the C bit to mean "Carry out," it uses it to mean "Borrow out."
This turns out to be exactly the opposite of "Carry out," and (like
the odd behavior of C on a load instruction) will end up being useful
for multiple-precision arithmetic.
There are also two instructions performing arithmetic between
the two accumulators: aba
, which adds the B accumulator
to the A accumulator, and sba
, which subtracts the B
accumulator from the A accumulator. These modify all the condition
codes appropriately.
We can increment or decrement an accumulator with inca
,
incb
, deca
, or decb
. These all
change N, Z, and V appropriately, but leave C unchanged.
There are also clr
, inc
and dec
instructions which operate on a byte in memory, and set the N, Z, and
V condition codes. These are useful primarily for maintaining things
like loop counters if both accumulators are in use for another
purpose, since they are quite slow (but not so slow as saving the
contents of an accumulator, loading the loop counter, changing the
loop counter, saving the loop counter, and reloading the old register
contents).