## How to read both return values from __udivmodhi4

8 posts / 0 new
Author
Message

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

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

Regards,
Steve A.

The Board helps those that help themselves.

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.

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

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

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

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

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]