Но всё же даже у гнуса бывают косяки с указателями.
И всего-то с двумя:
Код
case USART_SEND_DATA_EX:
length = 4 + 4 + 4 + 20;
*pb++ = length + 1;
*pb++ = command;
*pb++ = temperature.cpu;
*pb++ = temperature.gpu;
*pb++ = temperature.amb;
*pb++ = temperature.hdd;
*pb++ = fan_speed[FAN_CPU];
*pb++ = fan_speed[FAN_SIDE];
*pb++ = fan_speed[FAN_REAR];
*pb++ = fan_speed[FAN_FRONT];
*pb++ = cpuFan.GetManualStatus();
*pb++ = rearFan.GetManualStatus();
*pb++ = sideFan.GetManualStatus();
*pb++ = frontFan.GetManualStatus();
*pb++ = cpuFan.minRPM;
*pb++ = cpuFan.maxRPM;
*pb++ = cpuFan.minCELSIUS;
*pb++ = cpuFan.maxCELSIUS;
*pb++ = cpuFan.stopCELSIUS;
*pb++ = rearFan.minRPM;
*pb++ = rearFan.maxRPM;
*pb++ = rearFan.minCELSIUS;
*pb++ = rearFan.maxCELSIUS;
*pb++ = rearFan.stopCELSIUS;
*pb++ = sideFan.minRPM;
*pb++ = sideFan.maxRPM;
*pb++ = sideFan.minCELSIUS;
*pb++ = sideFan.maxCELSIUS;
*pb++ = sideFan.stopCELSIUS;
*pb++ = frontFan.minRPM;
*pb++ = frontFan.maxRPM;
*pb++ = frontFan.minCELSIUS;
*pb++ = frontFan.maxCELSIUS;
*pb++ = frontFan.stopCELSIUS;
код получается сплошняком из LDS/STS, так как адреса переменных (члены классов) статические и гнус таким образом "оптимизирует".
После того, как я перевёл приёмник в локальные переменные (пришлось водрузить буффер на стёк), код немного улучшился:
Код
case USART_SEND_DATA_EX:
length = 4 + 4 + 4 + 20;
*pb++ = length + 1;
1320: 81 e2 ldi r24, 0x21; 33
1322: 8b 83 std Y+3, r24; 0x03
*pb++ = command;
1324: 0c 83 std Y+4, r16; 0x04
*pb++ = temperature.cpu;
1326: 80 91 62 01 lds r24, 0x0162
132a: 8d 83 std Y+5, r24; 0x05
*pb++ = temperature.gpu;
132c: 80 91 63 01 lds r24, 0x0163
1330: 8e 83 std Y+6, r24; 0x06
*pb++ = temperature.amb;
1332: 80 91 64 01 lds r24, 0x0164
1336: 8f 83 std Y+7, r24; 0x07
*pb++ = temperature.hdd;
1338: 80 91 65 01 lds r24, 0x0165
133c: 88 87 std Y+8, r24; 0x08
*pb++ = fan_speed[FAN_CPU];
133e: 80 91 9d 01 lds r24, 0x019D
1342: 89 87 std Y+9, r24; 0x09
*pb++ = fan_speed[FAN_SIDE];
1344: 80 91 9e 01 lds r24, 0x019E
1348: 8a 87 std Y+10, r24; 0x0a
*pb++ = fan_speed[FAN_REAR];
134a: 80 91 9f 01 lds r24, 0x019F
134e: 8b 87 std Y+11, r24; 0x0b
*pb++ = fan_speed[FAN_FRONT];
1350: 80 91 a0 01 lds r24, 0x01A0
1354: 8c 87 std Y+12, r24; 0x0c
*pb++ = cpuFan.GetManualStatus();
1356: 8f e0 ldi r24, 0x0F; 15
1358: 92 e0 ldi r25, 0x02; 2
135a: 83 d8 rcall .-3834 ; 0x462 <CFanRegulatorBase::GetManualStatus()>
135c: 8d 87 std Y+13, r24; 0x0d
*pb++ = rearFan.GetManualStatus();
135e: 8c e1 ldi r24, 0x1C; 28
1360: 92 e0 ldi r25, 0x02; 2
1362: 7f d8 rcall .-3842 ; 0x462 <CFanRegulatorBase::GetManualStatus()>
1364: 8e 87 std Y+14, r24; 0x0e
*pb++ = sideFan.GetManualStatus();
1366: 89 e2 ldi r24, 0x29; 41
1368: 92 e0 ldi r25, 0x02; 2
136a: 7b d8 rcall .-3850 ; 0x462 <CFanRegulatorBase::GetManualStatus()>
136c: 8f 87 std Y+15, r24; 0x0f
*pb++ = frontFan.GetManualStatus();
136e: 86 e3 ldi r24, 0x36; 54
1370: 92 e0 ldi r25, 0x02; 2
1372: 77 d8 rcall .-3858 ; 0x462 <CFanRegulatorBase::GetManualStatus()>
1374: 88 8b std Y+16, r24; 0x10
*pb++ = cpuFan.minRPM;
1376: 80 91 18 02 lds r24, 0x0218
137a: 89 8b std Y+17, r24; 0x11
*pb++ = cpuFan.maxRPM;
137c: 80 91 17 02 lds r24, 0x0217
1380: 8a 8b std Y+18, r24; 0x12
*pb++ = cpuFan.minCELSIUS;
1382: 80 91 1a 02 lds r24, 0x021A
1386: 8b 8b std Y+19, r24; 0x13
*pb++ = cpuFan.maxCELSIUS;
1388: 80 91 19 02 lds r24, 0x0219
138c: 8c 8b std Y+20, r24; 0x14
*pb++ = cpuFan.stopCELSIUS;
138e: 80 91 1b 02 lds r24, 0x021B
1392: 8d 8b std Y+21, r24; 0x15
*pb++ = rearFan.minRPM;
1394: 80 91 25 02 lds r24, 0x0225
1398: 8e 8b std Y+22, r24; 0x16
*pb++ = rearFan.maxRPM;
139a: 80 91 24 02 lds r24, 0x0224
139e: 8f 8b std Y+23, r24; 0x17
*pb++ = rearFan.minCELSIUS;
13a0: 80 91 27 02 lds r24, 0x0227
13a4: 88 8f std Y+24, r24; 0x18
*pb++ = rearFan.maxCELSIUS;
13a6: 80 91 26 02 lds r24, 0x0226
13aa: 89 8f std Y+25, r24; 0x19
*pb++ = rearFan.stopCELSIUS;
13ac: 80 91 28 02 lds r24, 0x0228
13b0: 8a 8f std Y+26, r24; 0x1a
*pb++ = sideFan.minRPM;
13b2: 80 91 32 02 lds r24, 0x0232
13b6: 8b 8f std Y+27, r24; 0x1b
*pb++ = sideFan.maxRPM;
13b8: 80 91 31 02 lds r24, 0x0231
13bc: 8c 8f std Y+28, r24; 0x1c
*pb++ = sideFan.minCELSIUS;
13be: 80 91 34 02 lds r24, 0x0234
13c2: 8d 8f std Y+29, r24; 0x1d
*pb++ = sideFan.maxCELSIUS;
13c4: 80 91 33 02 lds r24, 0x0233
13c8: 8e 8f std Y+30, r24; 0x1e
*pb++ = sideFan.stopCELSIUS;
13ca: 80 91 35 02 lds r24, 0x0235
13ce: 8f 8f std Y+31, r24; 0x1f
*pb++ = frontFan.minRPM;
13d0: 80 91 3f 02 lds r24, 0x023F
13d4: 88 a3 std Y+32, r24; 0x20
*pb++ = frontFan.maxRPM;
13d6: 80 91 3e 02 lds r24, 0x023E
13da: 89 a3 std Y+33, r24; 0x21
*pb++ = frontFan.minCELSIUS;
13dc: 80 91 41 02 lds r24, 0x0241
13e0: 8a a3 std Y+34, r24; 0x22
*pb++ = frontFan.maxCELSIUS;
13e2: 80 91 40 02 lds r24, 0x0240
13e6: 8b a3 std Y+35, r24; 0x23
*pb++ = frontFan.stopCELSIUS;
13e8: 80 91 42 02 lds r24, 0x0242
13ec: 8c a3 std Y+36, r24; 0x24
13ee: 10 e2 ldi r17, 0x20; 32
13f0: 04 c0 rjmp .+8 ; 0x13fa <usartSendCommand(unsigned char, void const*)+0x1ea>
но всё равно не хватило сообразительности задействовать второй указатель.
ИАР без проблем юзает здесь два указателя даже со статическим буффером pb...