In avr assembly, I wanted to divide a number by a constant.
I checked how to see how avr-gcc does it.
So in a c file I have :
#include
uint8_t divide_by_6(uint8_t x) {
return x / 6;
}
and when I run avr-gcc -O3 -mmcu=atmega16 -D__AVR_ATmega16__ -S main.c
it gives me:
divide_by_6:
ldi r25,lo8(-85)
mul r24,r25
mov r24,r1
clr r1
lsr r24
lsr r24
ret
But I do not understand what this assembly is doing.
How does this assembly code perform division?
Answer
-85 is 0xFFFFFFFFFFFFFFAB, so lo8(-85)
is 0xAB, which is 171.
The code is multiplying the argument by 171, and then returning the most significant byte of the product, shifted right by 2 (i.e. divided by 4).
So it's effectively returning x * 171 / (256 * 4) == x * 171 / 1024, which is approximately == x * 1 / 6 == x / 6.
No comments:
Post a Comment