Section
04 Part 09 – The DIVU & DIVS Instructions |

“When there is no enemy
within, the enemies outside cannot hurt you.” ~Winston Churchill |

Introduction

These
instructions are for division, and there are two of them. Just like MULU and MULS, one is for unsigned
and the other is for signed.

Before
we go any further, you must understand that there are multiple ways of
answering a divide equation. For
example:

10 ÷ 3 |

When
dividing 10 into 3 parts, you could say:

- The answer is 3.3 recurring
(3.3333333... etc).
- The answer is 3 r1 (3 remainder 1).

While
the first answer is the most accurate, the second answer is valid as well. It is of course, the second answer that DIVU
and DIVS will use. As far as the 68k is
concerned:

10 ÷ 3 = 3 r1. |

With 3
r1 being the answer, 3 is what we call the “quotient”, and 1 is what we call
the “remainder” (hence the letter “r”).
So now, when I say the words “quotient” or “remainder”, you’ll know what
I’m talking about.

The DIVU
Instruction

DIVU – Unsigned DIVide

This
instruction will divide the long-word of the destination operand by the word
of the source
operand. The result is split into the quotient, and
the remainder. The remainder is saved in
the upper word of the destination operand, while the quotient is saved in the lower word of the destination operand.

If
the quotient is larger than a word, the destination operand, remains unchanged.

Examples

So,
we’ll start with this:

divu.w #$0002,d0 |

We’ll
pretend that d0 contains 00000803 for this example. So we have the long-word of d0, divided by the word 0002.

00000803 ÷ 0002 = 0401 r0001 |

The
answer is 401 r1 (quotient = 0401, remainder = 0001), and so d0 will now contain 00010401.

The destination operand ** must** be a data register; the source operand however, can be an immediate number, a data
register, a memory address, or even a memory address using an address
register. A few examples:

divu.w d1,d0 divu.w $00000010,d0 divu.w (a0),d0 |

The
only thing you ** cannot** use for
the source
operand is an
address register directly:

divu.w a0,d0 |

Finally,
only word can be used for the size.

The DIVS
Instruction

DIVS – Signed DIVide

This is
exactly the same as the DIVU instruction.
Except the source and destination are both treated as “signed”
instead of “unsigned”. So this
instruction can divide negative numbers as well as positive.

Examples

We’ll
pretend that d0 contains FFFFFFF8 in this example.

divs.w #$0002,d0 |

So,
the long-word FFFFFFF8 from d0
is divided by the word 0002.

FFFFFFF8 ÷ 0002 = FFFC r0000 |

FFFFFFF8
is treated as negative, and the quotient result FFFC is also negative. So what you really have is:

-00000008 ÷ +0002 = -00000004 |

And
so, d0 now contains 0000FFFC (-4 r0).

Please
note, if the destination
operand is
positive to begin with, then the remainder is also positive. If the destination operand is negative, then the remainder is also negative. Unless of course, the remainder is 0000, then
it stays as... Well 0000.

Apart
from the signed/unsigned differences, DIVS is the same as DIVU.

Invalid
situations

The
division process is relatively simple; however, there are a few situations where
divide will simply not work. For
example, if we pretend that d0 contains 00040000, and we perform this
instruction:

divu.w #$0004,d0 |

We
then have:

00040000 ÷ 0004 = 10000 r0000 |

Notice
how the quotient is 10000. The maximum a quotient result can be for
unsigned is FFFF (a word size). If you get a quotient result that is higher
than FFFF, then the divide instruction
will ** not** put the answer
inside d0. Instead, d0 will stay as 00040000, and the 68k will continue as if nothing
happened.

The
same applies for signed numbers that result in; a number higher than 0000FFFF
for positive, or lower than FFFF0000 for negative.

Here
is another interesting situation where the divide instruction cannot divide:

divu.w #$0000,d0 |

In
the rules of mathematics, you cannot divide a number by 0; it is defined as
impossible to calculate an answer. If
you attempt to divide by 0, the 68k will halt, and run a “divide by zero exception
routine” (we’ll be getting to exception routines later on in time, so don’t
worry about them for now).

It
would seem logical to me if they simply made it so that; if a divide by 0
occurs, make the result automatically 0.
Despite it going against the rules of mathematics, from a simple
programming perspective, it may very well have proved to be useful. Well, that’s my rant over. But you get the idea.

Homework

By
now, you should know about:

- Signed and unsigned numbers
- Bit shifting
- Bit rotation
- Multiplication & division
instructions

So,
here’s a list of instructions:

move.w #$0010,d0 mulu.w #$0003,d0 neg.w d0 ext.l d0 asr.l #$01,d0 ror.w #$01,d0 ext.l d0 divu.w #$0002,d0 |

d0
will start with 00000000. See if you can
work out what d0 will contain at the end of this. Once again, you are free to use a hex
calculator at any time. These are to
ensure that you understand how the instructions work, they’re not here to test
your mathematical skills.