original method (doesn't work)
static uint16_t readSnTX_WR(SOCKET _s) {
uint16_t res = readSn(_s, 0x0024);
res = (res << 8) + readSn(_s, 0x0025);
return res;
}
000003f4 <_ZN10W5100Class11readSnTX_WREh>:
3f4: ef 92 push r14
3f6: ff 92 push r15
3f8: 1f 93 push r17
3fa: cf 93 push r28
3fc: df 93 push r29
3fe: 18 2f mov r17, r24 ;
400: 64 e2 ldi r22, 0x24 ; 36
402: 70 e0 ldi r23, 0x00 ; 0
404: 0e 94 ab 00 call 0x156 ; 0x156 <_ZN10W5100Class6readSnEhj>
[glow] 408: 80 e0 ldi r24, 0x00 ; 0 !!!1[/glow]
[glow] 40a: ec 01 movw r28, r24 ; !!!2[/glow]
40c: 81 2f mov r24, r17
40e: 65 e2 ldi r22, 0x25 ; 37
410: 70 e0 ldi r23, 0x00 ; 0
412: 0e 94 ab 00 call 0x156 ; 0x156 <_ZN10W5100Class6readSnEhj>
416: c8 0f add r28, r24
418: d1 1d adc r29, r1
41a: ce 01 movw r24, r28
41c: df 91 pop r29
41e: cf 91 pop r28
420: 1f 91 pop r17
422: ff 90 pop r15
424: ef 90 pop r14
426: 08 95 ret
As I understand, readSn method returns its 8-bit result value in r24, but
-
!!!1 - actual result of high-byte gets always zeroed!
-
!!!2 - r25 gets written into r29, which has undefined value at this point, and it ends up in the high byte of the result!
Compiler messes up when trying to write 8-bit method return value to 16-bit variable??!?
Slightly rewritten, but equivalent method which works:
static uint16_t readSnTX_WR(SOCKET _s) {
uint8_t hi = readSn(_s, 0x0024);
uint8_t lo = readSn(_s, 0x0025);
uint16_t res = hi;
res = (res << 8) + lo;
return res;
}
000003f4 <_ZN10W5100Class11readSnTX_WREh>:
3f4: 0f 93 push r16
3f6: 1f 93 push r17
3f8: 18 2f mov r17, r24
3fa: 64 e2 ldi r22, 0x24 ; 36
3fc: 70 e0 ldi r23, 0x00 ; 0
3fe: 0e 94 ab 00 call 0x156 ; 0x156 <_ZN10W5100Class6readSnEhj>
402: 08 2f mov r16, r24
404: 81 2f mov r24, r17
406: 65 e2 ldi r22, 0x25 ; 37
408: 70 e0 ldi r23, 0x00 ; 0
40a: 0e 94 ab 00 call 0x156 ; 0x156 <_ZN10W5100Class6readSnEhj>
40e: 30 2f mov r19, r16
410: 20 e0 ldi r18, 0x00 ; 0
412: 28 0f add r18, r24
414: 31 1d adc r19, r1
416: c9 01 movw r24, r18
418: 1f 91 pop r17
41a: 0f 91 pop r16
41c: 08 95 ret
... assembly looks correct and it's even smaller.
[edit]Added analysis[/edit]