Посмотрел внимательнее. Судя по всему, компилятор - IAR. Действительно, иногда у него так бывает, жадность до регистров (т.е. не портить лишнего) пересиливает CSE.
Я в таких случаях делаю код вот такого плана:
Код
static void fooxx_stage2(uint8_t var1, uint8_t var2, uint8_t var3, uint8_t var4);
void fooxx(void)
{
fooxx_stage2(15,61,45,1);
}
static void fooxx_stage2(uint8_t var1, uint8_t var2, uint8_t var3, uint8_t var4)
{
for(uint16_t ii=0; ii<1000; ii++)
{
DDRD = var1;
PORTC = var2;
DDRD = var3;
DDRB = var4;
}
}
CODE
RSEG CODE:CODE:NOROOT(1)
// 7 void fooxx(void)
fooxx:
// 8 {
// 9 fooxx_stage2(15,61,45,1);
LDI R19, 1
LDI R18, 45
LDI R17, 61
LDI R16, 15
REQUIRE fooxx_stage2
; // Fall through to label fooxx_stage2
// 10 }
// 11
RSEG CODE:CODE:NOROOT(1)
// 12 static void fooxx_stage2(uint8_t var1, uint8_t var2, uint8_t var3, uint8_t var4)
fooxx_stage2:
// 13 {
MOVW R21:R20, R25:R24
// 14 for(uint16_t ii=0; ii<1000; ii++)
LDI R24, 232
LDI R25, 3
// 15 {
// 16 DDRD = var1;
??fooxx_stage2_0:
OUT 0x0A, R16
// 17 PORTC = var2;
OUT 0x08, R17
// 18 DDRD = var3;
OUT 0x0A, R18
// 19 DDRB = var4;
OUT 0x04, R19
// 20 }
SBIW R25:R24, 1
BRNE ??fooxx_stage2_0
// 21 }
MOVW R25:R24, R21:R20
RET
Но лучше так делать только при сильной необходимости.
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин