Может кому интересно CRC-32-IEEE 802.3 (0x04C11DB7) на AtmelStudio:
CRC32 по классификации WiKipedia:
Name : CRC 32
Width : 32
Poly : 04C11DB7
Init : FFFFFFFF
RefIn : True
RefOut : True
XorOut : FFFFFFFF
Check : CBF43926 (на проверочную комбинацию "123456789" )
Расчёт CRC побито во:
// 0x04C11DB7
uint32_t CRC_32(uint32_t __crc, uint8_t __data);
uint32_t ReversDW(uint32_t __crc);
uint32_t CRC_32(uint32_t __crc, uint8_t __data)
{
uint32_t __ret; /*%D0:%C0:%B0:%A0 (alias for __crc) */
uint32_t __tmp1; /* %D1:%C1:%B1:%A1 */
uint8_t __tmp2; /* %2 */
/* %3 __data */
__asm__ __volatile__ (
"mov __tmp_reg__,%3" "\n\t" /* crc.lo ^ data */
"ldi %A1, 0xB7" "\n\t"
"ldi %B1, 0x1D" "\n\t"
"ldi %C1, 0xC1" "\n\t"
"ldi %D1, 0x04" "\n\t"
"ldi %2, 8" "\n\t"
"CRC32_1:" "\n\t"
"lsr __tmp_reg__" "\n\t"
"rol %A0" "\n\t"
"rol %B0" "\n\t"
"rol %C0" "\n\t"
"rol %D0" "\n\t"
"brcc CRC32_2" "\n\t"
"eor %A0, %A1" "\n\t"
"eor %B0, %B1" "\n\t"
"eor %C0, %C1" "\n\t"
"eor %D0, %D1" "\n\t"
"CRC32_2:"
"dec %2" "\n\t"
"brne CRC32_1" "\n\t"
: "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2)
: "r" (__data), "0" (__crc)
: "r0"
);
return __ret;
}
// зеркалит вход
uint32_t ReversDW(uint32_t __crc)
{
uint32_t __ret; /*%D0:%C0:%B0:%A0 (alias for __crc) */
__asm__ __volatile__ (
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"rol %D0" "\n\t"
"ror %A0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
"rol %C0" "\n\t"
"ror %B0" "\n\t"
: "=d" (__ret)
: "0" (__crc)
);
return __ret;
}
Пример расчёта:
uint32_t crc;
uint32_t temp = 0x46AF6449;
temp = CRC_32(temp,'1');
temp = CRC_32(temp,'2');
temp = CRC_32(temp,'3');
temp = CRC_32(temp,'4');
temp = CRC_32(temp,'5');
temp = CRC_32(temp,'6');
temp = CRC_32(temp,'7');
temp = CRC_32(temp,'8');
temp = CRC_32(temp,'9');
temp = CRC_32(temp,0);
temp = CRC_32(temp,0);
temp = CRC_32(temp,0);
temp = CRC_32(temp,0);
crc = ~ReversDW(temp);
Пояснения:
Начальное значение 0x46AF6449 это потому, что сначала прокручивается 0xFFFFFFFF через:
for (i=0; i‹32; i++) {
bit = crc & 1;
if (bit) crc^= polynom;
crc ››= 1;
if (bit) crc|= crchighbit;
}
Исходники и пример расчёта:
http://www.zorc.breitbandkatze.de/crc.html