Section
02 Part 01 – The ADD Instruction |
“If you think dogs can't count, try putting three dog biscuits in your pocket and then giving Fido only two of them.” ~Phil Pastoret |
Introduction
ADD – ADD binary
This
instruction will add the number from the source operand to the destination operand; the source
operand will
remain unchanged.
Examples
Before
we begin, feel free to use a “hex calculator” at any time. You aren’t expected to know how to calculate
hexadecimal/binary numbers in your head (if you can do that, great, but it
isn’t necessary to program). You can
find hex calculators freely available online, your operating system might have
one too, go take a look.
Here’s
an example of the ADD instruction in use:
addi.b #$08,d0 |
This
will add the byte 08 to the byte in data register d0:
Of
course, let’s not forget, we’re only adding a byte so:
By
now you may understand that FF is the highest number in a byte (in hex), just
like 99 is the highest number out of a 2 digit decimal number. Adding 1 to 99 (in decimal) results in 100,
for hex it would be the same thing, adding 1 to FF (in hex) results in 100.
But
in the above examples, you may notice the example of “if d0 started with 222222FC”. You may think that adding 8 would result in
22222304, and this would normally be correct. But remember, we’re only adding a byte, so only the right byte is
affected, and the nybble “2” is not increased by 1.
Let’s
have an example using word:
addi.w #$1021,d0 |
This
will add the word 1021 to the word in data register d0:
You
may have noticed in the third example of “if d0 started with 4444FFFF”, FFFF add 1021 equals 11020, because we’re only
adding a word, the 5th nybble on the left there won’t add to the 4,
and won’t save as 5.
Other
Examples
You
can add numbers from one register to another as well, for example:
add.w d0,d1 |
This
will add a word of data from d0
to d1.
The
0100 was copied from d0 and added to the 0100 of d1, resulting in 0200.
Add
to and from memory:
add.w d0,$00001012 |
This
will copy the word in d0,
and add it into memory at offset $00001012. If d0 contains 1F400022, and the
bytes at memory $00001012
and $00001013 are 00 and 20, then 0022 +
0020 = 0042. 00 42 are therefore moved
into memory at offsets 00001012 and 00001013:
Offset |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
00001000 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00001010 |
00 |
00 |
00 |
42 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00001020 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00001030 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You
can add data from memory to a data register:
add.w $00001050,d0 |
If d0 contains 00121000, and the
data in memory is:
Offset |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
00001030 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00001040 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00001050 |
50 |
10 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00001060 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5010 is copied out of memory and
added to the word 1000 inside d0. d0 will then contain 00126010.
Unfortunately,
you cannot add data from
memory to memory:
add.b $00000010,$00000015 |
However,
there are ways around this:
move.b $00000010,d0 add.b d0,$00000015 |
As
you can see, we copied the data from memory at offset 00000010 to a data
register first, and then added the data register to the other memory at offset
00000015.
Just
like the move instruction, the address registers can be used for add too:
add.w d1,$72(a0) add.l $40(a0),d4 add.w d5,(a1) addi.b #$98,(a0)+ add.w a1,d0 |
However,
you cannot add from memory to
memory using the address registers:
add.w (a0),(a1) add.l (a0)+,$10(a2) add.w $9E(a4),-(a3) add.b $10(a0),$10(a6) |
Again,
there are ways around it. Like above,
you can use the move instruction to move the data to a data register first, and
then add it from the data register to the memory offset in the address register
Add
Immediate
You
may have noticed that in some of the instructions above, I had put an “i” on the end. The “i” stands for “immediate”.
You may remember on Section 01 Part 03 we talked about the # symbol
being for immediate
numbers, i.e:
addi.b #$20,d0 |
Because
the source
operand is
“immediate”, the addi instruction must be used
instead of add. However, don’t worry if you use just plain old “add” instead, as the
assembler will turn it into addi for you, when it
assembles your code.