Ralph Doncaster schrieb:
I wrote a small function to convert u8 to hex:
// converts 4-bit nibble to ascii hex
uint8_t nibbletohex(uint8_t value)
{
if ( value > 9 ) value += 'A' - '0';
return value + '0';
}
// returns value as 2 ascii characters in a 16-bit int
uint16_t u8tohex(uint8_t value)
{
uint16_t hexdigits;
uint8_t hidigit = (value >> 4);
hexdigits = (nibbletohex(hidigit) << 8);
uint8_t lodigit = (value & 0x0F);
hexdigits |= nibbletohex(lodigit);
return hexdigits;
}
I compiled it with avr-gcc -Os using 4.8 and 5.1 and got the same code:
0000007a <u8tohex.1416>:
7a: 28 2f mov r18, r24
7c: 22 95 swap r18
7e: 2f 70 andi r18, 0x0F ; 15
80: 2a 30 cpi r18, 0x0A ; 10
82: 08 f0 brcs .+2 ; 0x86 <u8tohex.1416+0xc>
84: 2f 5e subi r18, 0xEF ; 239
86: 20 5d subi r18, 0xD0 ; 208
88: 30 e0 ldi r19, 0x00 ; 0
8a: 32 2f mov r19, r18
8c: 22 27 eor r18, r18
8e: 8f 70 andi r24, 0x0F ; 15
90: 8a 30 cpi r24, 0x0A ; 10
92: 08 f0 brcs .+2 ; 0x96 <u8tohex.1416+0x1c>
94: 8f 5e subi r24, 0xEF ; 239
96: 80 5d subi r24, 0xD0 ; 208
98: a9 01 movw r20, r18
9a: 48 2b or r20, r24
9c: ca 01 movw r24, r20
9e: 08 95 ret
There's some completely pointless code there, like loading 0 to r19
and immediately overwriting it with the contents of r18 (88, 8a).
Other register use is convoluted. The compiler should at least be
able to generate the following code (5 fewer instructions):
28 2f mov r18, r24
22 95 swap r18
2f 70 andi r18, 0x0F ; 15
2a 30 cpi r18, 0x0A ; 10
08 f0 brcs .+2 ; 0x86 <u8tohex.1416+0xc>
2f 5e subi r18, 0xEF ; 239
20 5d subi r18, 0xD0 ; 208
32 2f mov r25, r18
8f 70 andi r24, 0x0F ; 15
8a 30 cpi r24, 0x0A ; 10
08 f0 brcs .+2 ; 0x96 <u8tohex.1416+0x1c>
8f 5e subi r24, 0xEF ; 239
80 5d subi r24, 0xD0 ; 208
08 95 ret
Looks like PR41076