How to read both return values from __udivmodhi4

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

In AVR341 application note there is an implementation of an utoa function, shown below.

/*************************************************************************
Function: utoa()
Purpose:  convert unsigned integer to ascii  
Input:    string_buffer, string_buffer_size, unsigned integer value
Returns:  first ascii character
**************************************************************************/
char *utoa(char* buffer, const unsigned int size, unsigned int value)
{
  char *p;
 
  // p points to last char
  p = buffer+size-1;
  
  // Set terminating Zero 
  *p='\0';
  
  do 
  {
    *--p = value%10 + '0';
    value = value/10;
  } while (value!=0 && p>buffer);
  
  return p;
}/* utoa */

The divide and module part (inside the do while loop) is compiled by avr-gcc in this way:

    *--p = value%10 + '0';
 1d0:	c9 01       	movw	r24, r18
 1d2:	6a e0       	ldi	r22, 0x0A	; 10
 1d4:	70 e0       	ldi	r23, 0x00	; 0
 1d6:	1e d0       	rcall	.+60     	; 0x214 <__udivmodhi4>
 1d8:	80 5d       	subi	r24, 0xD0	; 208
 1da:	82 93       	st	-Z, r24
    value = value/10;
 1dc:	c9 01       	movw	r24, r18
 1de:	6a e0       	ldi	r22, 0x0A	; 10
 1e0:	70 e0       	ldi	r23, 0x00	; 0
 1e2:	18 d0       	rcall	.+48     	; 0x214 <__udivmodhi4>
 1e4:	9b 01       	movw	r18, r22

So we can see that there is two identical calls to __udivmodhi4, that returns the remainder in r24 and the quotient in r22.

So, finally, here is the question. Is there a way, in C (GCC), to get both results without calling __udivmodhi4 two times?

Felipe Maimon

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, use the standard library function "div" (or "ldiv" if you want longs).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

fmaimon wrote:
Hi,

In AVR341 application note there is an implementation of an utoa function, shown below.

AVR-LibC already comes with a utoa() function and and itoa() function, found in . There's no need to write your own.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EW wrote:
AVR-LibC already comes with a utoa() function and and itoa() function, found in . There's no need to write your own.

That was just an example, that I've stumbled upon reading the application note AVR341 (written in IAR).

Thank you guy, for the answers.

Felipe Maimon

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

fmaimon wrote:
Is there a way, in C (GCC), to get both results without calling __udivmodhi4 two times?
You can do so fairly easily using some assembly language code, either inline or standalone.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But why resort to Asm? Steve already suggested using the div() function in stdlib.h:

#include  
#include 

int main() 
{
	div_t result;

	result = div(12345, 10);

	PORTB = result.quot; 
	PORTC = result.rem;
}

yields:

00000052 
: int main() { div_t result; result = div(12345, 10); 52: 89 e3 ldi r24, 0x39 ; 57 54: 90 e3 ldi r25, 0x30 ; 48 56: 6a e0 ldi r22, 0x0A ; 10 58: 70 e0 ldi r23, 0x00 ; 0 5a: 05 d0 rcall .+10 ; 0x66 <__divmodhi4> PORTB = result.quot; 5c: 65 b9 out 0x05, r22 ; 5 PORTC = result.rem; 5e: 88 b9 out 0x08, r24 ; 8

with a single call to the library function.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
But why resort to Asm? Steve already suggested using the div() function in stdlib.h:

#include  
#include 

int main() 
{
	div_t result;

	result = div(12345, 10);

	PORTB = result.quot; 
	PORTC = result.rem;
}

yields:

00000052 
: int main() { div_t result; result = div(12345, 10); 52: 89 e3 ldi r24, 0x39 ; 57 54: 90 e3 ldi r25, 0x30 ; 48 56: 6a e0 ldi r22, 0x0A ; 10 58: 70 e0 ldi r23, 0x00 ; 0 5a: 05 d0 rcall .+10 ; 0x66 <__divmodhi4> PORTB = result.quot; 5c: 65 b9 out 0x05, r22 ; 5 PORTC = result.rem; 5e: 88 b9 out 0x08, r24 ; 8

with a single call to the library function.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

anks18 wrote:

clawson wrote:
[...]

He certainly did.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]