| Section
  02 Part 02 – The SUB Instruction | 
| “If people do not believe that mathematics is simple, it is only because they do not realize how complicated life is.” ~John Louis von Neumann | 
 
Introduction
SUB – SUBtract
binary
This
instruction will subtract the number of the source operand from the destination operand; the source
operand will
remain unchanged.
Examples
This
here is obviously the exact opposite of ADD, and here’s an example of the SUB
instruction in use:
|           subi.b    #$10,d0 | 
This
will subtract the byte 10 from the byte in data register d0:
Of
course, let’s not forget, we’re only subtracting a byte so:
Just
about every instruction has the same principle, only the right byte is
affected.
Let’s
have an example using word:
|           subi.w    #$0200,d0 | 
This
will subtract the word 0200 from the word in data register d0:
Once
again, only the right words are affected.
Other
Examples
You
can subtract numbers of one register from another, for example:
|           sub.l     d0,d1 | 
This
will subtract a long-word of data in d0
from d1.
You
can subtract data from memory:
|           sub.w     d0,$0000102E | 
This will
copy the word in d0, and subtract it from memory
at offset $0000102E.  If d0
contains 09920022, and the bytes at memory $0000102E and
$0000102F are 00
and 2E, then 002E – 0022 = 000C.  00 0C
are therefore moved into memory at offsets 0000102E and 0000102F:
| 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 | 00 | 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 | 0C | 
| 00001030 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 
| etc |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 
You
can subtract data in memory from a data register:
|           sub.b     $00001040,d0 | 
If d0 contains 00121080, 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 | 70 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 
| 00001050 | 00 | 00 | 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 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 
70 is copied out of memory and
subtracted from the byte 80 inside d0.  d0 will then contain 00121010.
Unfortunately,
you cannot subtract data in
memory location from another memory location:
|           sub.b     $00000120,$00000124 | 
However,
just like the add instruction, the same methods of getting around work just as
well:
 
|           move.b    $00000120,d0           sub.b     d0,$00000124 | 
As
you can see, we copied the data from memory at offset 00000120 to a data
register first, and then subtracted the data register from the other memory at
offset 00000124.
You
can use the address registers too:
|           sub.w     d1,$72(a0)           sub.l     $40(a0),d4           sub.w     d5,(a1)           subi.b    #$98,(a0)+           sub.w     a1,d0 | 
However,
you cannot subtract from memory
to memory using the address registers:
|           sub.w     (a0),(a1)           sub.l     (a0)+,$10(a2)           sub.w     $9E(a4),-(a3)           sub.b     $10(a0),$10(a6) | 
Sub
Immediate
Just
like the add instruction, if the source operand is “immediate”, you must use the instruction “subi”
instead of “sub” (where the “i” stands for
immediate):
|           subi.b    #$20,d0 | 
Again,
don’t worry if you use just plain old “sub” instead, as the assembler will turn
it into subi for you, when it assembles your code.