I was trying to implement division by 10 in arm assembly. I followed the method mentioned in the first answer to the question at ARM DIVISION HOW TO DO IT?
This is my code
MOV r2, #10
LDR r3,=0x1999999A ; 1999999A == (2^32 / 10) + 1
UMULL r9,r3,r5,r3 ;divide an integer value in r5 by 10
MOV r6, r9,LSR r2 ; r6 has the quotient
But this code is not giving the correct result.For example, If I give 0x0000000B in r5, after these steps value in r6 is 0x00066666.
Am I doing anything wrong?
uint32(x / 10) = uint64(x * 0xcccccccd) >> 35
E.g. the following code will divide unsigned r5
by 10
with the quotient in r0
:
ldr r2,=0xcccccccd
umull r0,r1,r5,r2
mov r0,r1,lsr #3
There is a rather good writeup of division by constant http://thinkingeek.com/2013/08/11/arm-assembler-raspberry-pi-chapter-15/ It has a python script to generate the magic numbers and the code for any constant. For 10 it's
/* r0 contains the argument to be divided by 10 */
ldr r1, .Lu_magic_number_10 /* r1 ← magic_number */
umull r1, r2, r1, r0 /* r1 ← Lower32Bits(r1*r0). r2 ← Upper32Bits(r1*r0) */
mov r0, r2, LSR #3 /* r0 ← r2 >> 3 */
bx lr /* leave function */
.align 4
.Lu_magic_number_10: .word 0xcccccccd
And the arm website has the code on it, but i found it here now http://www.sciencezero.org/index.php?title=ARM:_Division_by_10
Note that this even manages without the later introduced 64bit multiplication.
User contributions licensed under CC BY-SA 3.0