Ответ:
Так выглядит на С:
unsigned char Buffer[64]; // буфер вывода данных
__regvar __no_init volatile unsigned char I1@11, I2@10; // указатели буферов
__regvar __no_init unsigned char SumTX@12; // контрольная сумма
void Push( unsigned char val )
{
SumTX ^= Buffer[I2] = val; // заталкиваем в КОЛЬЦЕВОЙ буфер, корректируем контрольную сумму
if( ++I2 >= 64 ) I2 = 0; // продвигаем указатель (сбрасывается на 0, когда доходит до конца)
}
--------------------------
v 3.20c:
void Push( unsigned char val )
`Push`:
REQUIRE ?Register_R10_is_global_regvar
REQUIRE ?Register_R12_is_global_regvar
SumTX ^= Buffer[I2] = val;
00000000 2D1A MOV R17,R10
00000002 .... LDI R30, Buffer
00000004 0FE1 ADD R30, R17
00000006 8300 ST Z, R16
00000008 26C0 EOR R12, R16
if( ++I2 >= 64 ) I2 = 0;
000000A 94A3 INC R10 // тут все хорошо, сделано одной командой
000000C E400 LDI R16, 64
000000E 16A0 CP R10, R16
0000010 F008 BRCS ??Push_0
0000012 24AA CLR R10
??Push_0:
0000014 9508 RET
--------------------------
v 4.10a:
void Push( unsigned char val )
`Push`:
REQUIRE ?Register_R10_is_global_regvar
REQUIRE ?Register_R12_is_global_regvar
SumTX ^= Buffer[I2] = val;
00000000 2D1A MOV R17, R10
00000002 .... LDI R30, Buffer
00000004 0FE1 ADD R30, R17
00000006 8300 ST Z, R16
00000008 26C0 EOR R12, R16
if( ++I2 >= 64 ) I2 = 0;
0000000A 2D0A MOV R16, R10 // копирует в другой регистр
0000000C 9503 INC R16 // там делает инкремент
0000000E 2EA0 MOV R10, R16 // копирует назад
00000010 3400 CPI R16, 64
00000012 F008 BRCS ??Push_0
00000014 24AA CLR R10
??Push_0:
00000016 9508 RET