Greatest Common Divisor in ARM Assembly
ARM(specifically ARM7) doesn’t have a division instruction (UDIV or SDIV), at least I’ve never seen any. That’s why we do it like the above (higher level understandable code)
int divide(int input, int divisor)
{
int result = 0;
while(input >= divisor)
{
input = input - divisor;
result++;
}
return result;
}
Even though this is not a short and simple code for an easy operation, Finding gcd is not really more difficult than that. I used an approach which includes both iteration and recursion.
int gcd(int x,int y){
while(x!=y)
{
if(x>y)
return gcd(x-y,y);
else
return gcd(x,y-x);
}
return x;
}
That last thing converting this to assembly code which is complicated and not understandable enough.
AREA gcdcalc, CODE, READWRITE
ENTRY
MOV R0,#30 ; test values
MOV R1,#45 ; test values
gcd
while CMP R0,R1
BEQ endw
BGT cond1
B cond2
cond1 SUB R0,R1
B gcd
cond2 SUB R1,R0
B gcd
B while
endw
stop B stop
END
That worked for me, I built and debugged this in Keil uVision 4 for ARM7 Little Endian device.
Version 2
##### More optimized algorithm and assembly code I’ve seen a more optimized and fast great common division algorithm, in one of my books. I am also more experienced in ARM Assembly, so that I could write shorter and better code for the algorithm.
GCD in ANSI-C
int gcd(int a, int b)
{
while(a != b)
{
if(a>b)
a = a - b;
else
b = b - a;
}
return a; // or b because they are equals
}
GCD in ARM Assembly
gcd CMP R1,R2
SUBGT SUB R1,R1,R2
SUBLT SUB R2,R2,R1
BNE gcd
It is even shorter than C code, thanks to instructions with condition.