1
votes

I m trying to find how to make a division in ARM since there is no DIV command. If that can be done by multiplication of a float number [/9 = *0.09], by subtraction or by the use of a library. Any way would do.

Currently I am doing division using subtraction using a loop like this but I loose the decimals:

MOV R0,#70 ;Fahrenheit Temperature
SUB R1,R0,#32 ; Subtracting 32
MOV R4,#0 ;Counter

LOOP 

   ADD R4,R4,#1; Counter+1 ->Is the answer of the division without decimals
   SUB R1,#9
   CMP R1,#0
   BPL LOOP
   MOV R1,R4

So basically what I am doing is that I have temperature 70, I subtract 32 and I get 38. Then in the loop I take 9 each time till the reminder is smaller than 9. The answer using normal division is 4.22222. Here I get 5. So my result is not as accurate.

2
possible duplicate of Fast Division on GCC/ARM - artless noise
It is better to multiply by something like (2^16/9~=7282) and then shift by 2^16 on the result. You have to know the range of values and this works only for a fixed division. - artless noise
Other related quesions: Integer division on ARM, Assembly mod algorithm; look at the related list at the side of the question. - artless noise
My ARM has a division instruction...why doesn't yours? Is there perhaps a little more information you could give us? - user1619508
homepage.cs.uiowa.edu/~jones/bcd/divide.html and just do that for any other number. yes you can use fixed or float to multiply by 1/9th for example. - old_timer

2 Answers

3
votes

If you just want to divide an integer value in r0 by 9 you can approximate that with:

ldr r3,=0x1C71C71D   # 1C71C71D == (2^32 / 9) + 1
umull   r9,r3,r0,r3

r3 now contains the integer part of the quotient, and r9 contains the fractional part scaled by 2^32. To get the remainder you'd just multiply the integer part of the quotient by 9 and subtract the result from the original value.

1
votes

Michael's answer is right if you divide the number by a constant and you need an integer result. You won't get the fraction part like you want.

If you need a floating-point result you'll need a floating-point division function, which is not easy to implement in software and asm on architectures without FPU. ARMv7 and above have FPU/SIMD by default, some ARMv6 and below also have FPU so you can divide it directly in hardware

A fixed-point solution may be easier, just divide the number like normal integer division but remember to adjust the result after calculation. Of course fixed-point number won't have large dynamic range like floating-point but in your case I think the range is enough. You can also multiply the remainder by 10n, with n is the number of digits after decimal sign you need, then divide it with the above divisor again to get the fractional part

For example to get the result of 22/9 with 3 digits of precision do as follow:

22/9   = 2 remains 4
4*10^3 = 4000
4000/9 = 444
→ 22/9 = 2.444

To get more precision, just multiply the remainder with a larger power of 10