HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

•  Subject
• Author
• Posted on
Deutsche Version weiter unten!

Hi!

I´ve got a problem with the Assembly language for Motorola 8-bit
microcontrollers:

how can I divide/multiply 2 8-bit variables with an 16-bit result?
syntax:

e.g. div-command

div  A <- (H:A) / X
H <- Remainder

e.g.: 130 / 100 (decimal)

=> 0x82 / 0x64

lda #\$64     ; move 0x64 to Accumulator
tax          ; move Accumulator to Index register low byte
lda #\$82     ; move 0x82 to Accumulator

div

result: 0x01 is stored in Accumulator
remainder 0x1E in Index register low byte

Goal: i´d like to calculate 85% of a measured value.
Idea (good, bad???): divide value by 100 and multiply t by 85

Thany a lot for your replies!

Und jetzt in Deutsch :-) :

Ich habe folgendes Problem:

Ich möchte auf einem 8-bit Mikrocontroller 2 8-bit Variablen
dividieren und multiplizieren, mit dem Ziel, von einem Wert 85% zu
berechnen.
Leider habe ich keine Ahnung wie das funktioniert.

Ich kann zwar dividieren (s.o), nur leider wird nur noch dem
modula-Verfahren dividert und ich kann mit dem Restbetrag nichts
anfangen.

Kann mir jemand weiterhelfen?

1000 Dank,
Kai

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result
[Note: Your post is obviously off-topic in the half the groups you
x-posted to, so I'm cutting down both the Newsgroups and the F'up2]

Essentially the same way you learned to divide and multiply
multi-digit numbers back in primary school, although you can only
memorize the "kleine 1x1". ;-)

Bad idea.  Rather multiply by 17, then divide by 20.

Or multiply by 217 = 256*85/100, and keep only the upper byte of the
16-bit result.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result

the idea is bad becouse you have integer and the 1% value cannot
carry the accuracy from the 100% value. Depending from the absolute
values, the result can be very inaccurate

das merkt man, du solltest deshalb vielleicht nicht gleich in so
vielen Gruppen posten

Es wird ein 16 bit Wert durch einen 8 bit Wert geteilt und das Ergebnis
gibt einen 8 bit Wert. Bei 85% von einem 16 bit Wert ist das Ergebnis
aber meist eben auch ein 16 bit Wert.

An Stelle von 85% ginge es Beispielsweise sehr einfach 87,5%
auszurechnen. Hierzu schiebst du den 100% Wert 3 mal nach rechts
was 12,5% vom Gesamtwert ausmacht. Sodann machst du eine Subtraktion
100%-12,5%87%,5%. Du kannst das auf diese Weise natürlich selbst noch
etwas genauer hintricksen undem du z.Bsp. nochmal 3,125% (nochmals 2x
rechts schieben) zusätzlich abziehst. So wird das Ergebnis immer
genauer. Der Code geht dann natürlich nur für den einen Fall von 85%,
aber danach hast du ja gefragt. Ist auch die schnellste und kleinste Lösung.

Wenn du es allgemein haben willst, würde ich bei www.cosmic-software.de die
freie Version des HC08 Compilers runterladen und von dort die Integer
Bibliothek rausklauen. Die Codelänge der Bibliothek ist wesentlich kleiner
als die von Metrowerks und es sind auch die Quellen davon in der Demo
drin so daß du sie mit anderen Werkzeugen zum übersetzen kriegen müsstest
wenn du sie nicht nur verstehen willst.

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result
On 5 Feb 2004 03:24:21 -0800, Kai hath writ:

Then you really should be posting in

comp.lang.Motorola-8-bit-microcontrollers  (oder etwas anders)

and not in

comp.lang.asm370

Re: HowTo DIV MUL in Assembler, Motorola,...
snipped-for-privacy@gmx.de (Kai) writes:

Better is to multiply first and then divide.  To get the 85%
value, first multiply by 85 (or 17) and then divide by 100
(or 20).

If you are trying to determine what 85% of 130/100 is, then
that's a different problem.  You will have to resort to
scaled, fixed-point operations to obtain anything meaningful.

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result

Well, this newsgroup is for IBM S/370 assembler.

(snip)

Well, on most machines I know about that is not a good way.

Much better is to multiply by 85 and then divide by 100.

That is the advantage of having multiplies where the product is
twice as long, and divide where the dividend is twice as long.

Say the number was 143.  Divide by 100 and you get 1, multiply
by 85 and you get 85.

But if you multiply 143 by 85 you get 12155, and divide by
100 you get 121.  Which one do you want?

Note, though, that S/370 doesn't have an 8 bit multiply
instruction.  It does have a 32 bit multiply with a 64 bit
product, and divide with a 64 bit dividend, 32 bit divisor
generating a 32 bit quotient and 32 bit remainder.

-- glen

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result
|> Kai wrote:
| Well, this newsgroup is for IBM S/370 assembler.
|> I´ve got a problem with the Assembly language for Motorola 8-bit
|> microcontrollers:
|>
|> how can I divide/multiply 2 8-bit variables with an 16-bit result?
|> syntax:

| (snip)

|> Goal: i´d like to calculate 85% of a measured value.
|> Idea (good, bad???): divide value by 100 and multiply t by 85
|
| Well, on most machines I know about that is not a good way.
|
| Much better is to multiply by 85 and then divide by 100.
|
| That is the advantage of having multiplies where the product is
| twice as long, and divide where the dividend is twice as long.
|
| Say the number was 143.  Divide by 100 and you get 1, multiply
| by 85 and you get 85.
|
| But if you multiply 143 by 85 you get 12155, and divide by
| 100 you get 121.  Which one do you want?
|
| Note, though, that S/370 doesn't have an 8 bit multiply
| instruction.  It does have a 32 bit multiply with a 64 bit
| product, and divide with a 64 bit dividend, 32 bit divisor
| generating a 32 bit quotient and 32 bit remainder.

Note that the System/370 (and older models) have a 16-bit
multiply (MH = multiply halfword). ___________________Gerard S.

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result

(snip)

It seems more natural to me to use the multiply with the
64 bit product followed by the divide, as there is no DH.

One could MH, sign extend the result, and then divide, though.
It might be faster on some machines.

One could also M with the appropriate constant, and use the
high half of the product for the result.  The rounding might
be a little different, but the result should be close.

0.85*2**3236%50722201.6

143*3650722201 will put 121 into the high word of the product.

-- glen

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result

Considering that

217/256=0.84765625 (error -0.0033),
218/256=0.85312500 (+0.0031),

thus (218*x) >> 8 can be implemented with unsigned 8x816% bit multiply
and using only the most significant byte of the result (equivalent of
shifting the 16 bit products right by 8 places). No division
instructions needed.

A slightly better result can be obtained by rounding, e.g. checking
the most significant bit of the discarded product byte and if this bit
is 1, add 1 to the retained product byte.

Paul

Re: HowTo DIV MUL in Assembler, Motorola, for 8-bit Microcontroller with an 16-bit result

As others have noted, some of the newsgroups Kai posted to aren't
appropriate for his platform.  However...

Your original value has only 8 bits of precision; how precise do you need
that 85% to be?  If it's OK to calculate 87.5%, then you can do the
following:

Load the original value into the accumulator
Shift it right 3 bits
Subtract this from original value; result is .875 of original value.

If that's not precise enough, you can get very close to .85 with only a few
more steps:

Load the original value into the accumulator
Shift it right 2 bits
Subtract this from original value; result is .75 of original value.
Save a copy of this intermediate value
Shift intermediate value right 3 bits
Add intermediate value to this shifted value; result is 112.5% of
intermediate value, 84.375% of oiginal value.  That's
right to 8 bits of precision.

Shifts, adds, and subtracts are much faster than multiplys or divides on
microprocessors, so an algorithm like this is usually preferred for such
"multiply by a constant" calculations.

--
Randy Hudson