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:

1. The answer is 3.3 recurring (3.3333333... etc).
2. 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

 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.