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:

• if d0 started with 00000000, after the instruction d0 will contain 00000008
• if d0 started with 00000010, after the instruction d0 will contain 00000018
• if d0 started with 00000004, after the instruction d0 will contain 0000000C
• if d0 started with 00000067, after the instruction d0 will contain 0000006F

Of course, let’s not forget, we’re only adding a byte so:

• if d0 started with 00001008, after the instruction d0 will contain 00001010
• if d0 started with 222222FC, after the instruction d0 will contain 22222204
• if d0 started with 333333FF, after the instruction d0 will contain 33333307

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:

• if d0 started with 00000010, after the instruction d0 will contain 00001031
• if d0 started with 000000DF, after the instruction d0 will contain 00001100
• if d0 started with 4444FFFF, after the instruction d0 will contain 44441020

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.

• If d0 contains FED00100, and d1 contains 00000100, after the instruction d1 will contain 00000200.

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.