Перейти к содержанию
    

Покопался я у себя в закромах и обнаружил когда-то найденную и бережно сохранённую

функцию для расчёта crc16.

 

;***************************************************************************
; (c) 1998 Alexander Trush        Http://troosh.pp.ru
;
;       Function UpdateCRC for computing CRC16 (poly 0x1021)
;
;    Вы можете свободно использовать, распространять, модифицировать этот
;    код до тех пор, пока вы указываете моё авторство и распространяете
;    это требование. Кроме того, я хотел бы получать уведомление о
;    применении этого кода по e-mail (troosh (at) kbotd : ru).


CRC_H:        .BYTE    1; CRC accum
CRC_L:        .BYTE    1

.DEF    HL_5    = r14
.DEF    HH_5    = r16; High Only
.DEF    H_1     = r15
.DEF    H_12    = r17; High Only

UpdateCRC:      lds     H_12, CRC_H
        mov     H_1, H_12
        swap    H_12
        mov     HH_5, H_12

        eor     H_12, H_1
        andi    H_12, 0xF0
        andi    HH_5, 0x0F
        eor     H_1, HH_5

        mov     HL_5, H_12
        lsl     HL_5
        rol     HH_5

        eor     H_1,  HL_5
        eor     H_12, HH_5

        lds     HL_5, CRC_L
        eor     H_1, ZH
        eor     H_12, HL_5

        sts     CRC_L, H_1
        sts     CRC_H, H_12
        ret

Попытался сравнить её по производительности с идущей в комплекте с WinAvr (понятно что полином другой).

/*
*  Optimized CRC-16 calculation.
*
*  Polynomial: x^16 + x^15 + x^2 + 1 (0xa001)
*  Initial value: 0xffff
*/
static __inline__ uint16_t
_crc16_update(uint16_t __crc, uint8_t __data)
{
    uint8_t __tmp;
    uint16_t __ret;

    __asm__ __volatile__ (
        "eor %A0,%2" "\n\t"
        "mov %1,%A0" "\n\t"
        "swap %1" "\n\t"
        "eor %1,%A0" "\n\t"
        "mov __tmp_reg__,%1" "\n\t"
        "lsr %1" "\n\t"
        "lsr %1" "\n\t"
        "eor %1,__tmp_reg__" "\n\t"
        "mov __tmp_reg__,%1" "\n\t"
        "lsr %1" "\n\t"
        "eor %1,__tmp_reg__" "\n\t"
        "andi %1,0x07" "\n\t"
        "mov __tmp_reg__,%A0" "\n\t"
        "mov %A0,%B0" "\n\t"
        "lsr %1" "\n\t"
        "ror __tmp_reg__" "\n\t"
        "ror %1" "\n\t"
        "mov %B0,__tmp_reg__" "\n\t"
        "eor %A0,%1" "\n\t"
        "lsr __tmp_reg__" "\n\t"
        "ror %1" "\n\t"
        "eor %B0,__tmp_reg__" "\n\t"
        "eor %A0,%1"
        : "=r" (__ret), "=d" (__tmp)
        : "r" (__data), "0" (__crc)
        : "r0"
    );
    return __ret;
}

И понял, что не хватает ни времени ни мозгов на это.

Для желающих потренировать извилины - добро пожаловать:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

понятно что полином другой
Понятно также, что из другого полинома вытекает совершенно другой алгоритм и сравнивать их не имеет никакого смысла. Возьмите реализацию для этого же полинома и сравнивайте с ней:
/** \ingroup util_crc
    Optimized CRC-XMODEM calculation.

    Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)<br>
    Initial value: 0x0

    This is the CRC used by the Xmodem-CRC protocol.

    The following is the equivalent functionality written in C.

    \code
    uint16_t
    crc_xmodem_update (uint16_t crc, uint8_t data)
    {
        int i;

        crc = crc ^ ((uint16_t)data << 8);
        for (i=0; i<8; i++)
        {
            if (crc & 0x8000)
                crc = (crc << 1) ^ 0x1021;
            else
                crc <<= 1;
        }

        return crc;
    }
    \endcode */

static __inline__ uint16_t
_crc_xmodem_update(uint16_t __crc, uint8_t __data)
{
    uint16_t __ret;             /* %B0:%A0 (alias for __crc) */
    uint8_t __tmp1;             /* %1 */
    uint8_t __tmp2;             /* %2 */
                                /* %3  __data */

    __asm__ __volatile__ (
        "eor    %B0,%3"          "\n\t" /* crc.hi ^ data */
        "mov    __tmp_reg__,%B0" "\n\t"
        "swap   __tmp_reg__"     "\n\t" /* swap(crc.hi ^ data) */

        /* Calculate the ret.lo of the CRC. */
        "mov    %1,__tmp_reg__"  "\n\t"
        "andi   %1,0x0f"         "\n\t"
        "eor    %1,%B0"          "\n\t"
        "mov    %2,%B0"          "\n\t"
        "eor    %2,__tmp_reg__"  "\n\t"
        "lsl    %2"              "\n\t"
        "andi   %2,0xe0"         "\n\t"
        "eor    %1,%2"           "\n\t" /* __tmp1 is now ret.lo. */

        /* Calculate the ret.hi of the CRC. */
        "mov    %2,__tmp_reg__"  "\n\t"
        "eor    %2,%B0"          "\n\t"
        "andi   %2,0xf0"         "\n\t"
        "lsr    %2"              "\n\t"
        "mov    __tmp_reg__,%B0" "\n\t"
        "lsl    __tmp_reg__"     "\n\t"
        "rol    %2"              "\n\t"
        "lsr    %B0"             "\n\t"
        "lsr    %B0"             "\n\t"
        "lsr    %B0"             "\n\t"
        "andi   %B0,0x1f"        "\n\t"
        "eor    %B0,%2"          "\n\t"
        "eor    %B0,%A0"         "\n\t" /* ret.hi is now ready. */
        "mov    %A0,%1"          "\n\t" /* ret.lo is now ready. */
        : "=d" (__ret), "=d" (__tmp1), "=d" (__tmp2)
        : "r" (__data), "0" (__crc)
        : "r0"
    );
    return __ret;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понятно также, что из другого полинома вытекает совершенно другой алгоритм и сравнивать их не имеет никакого смысла. Возьмите реализацию для этого же полинома и сравнивайте с ней
Точно! Спасибо:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...