【问题标题】:Assembly AVR ATMEGA128: CRC Algorithm汇编 AVR ATMEGA128:CRC 算法
【发布时间】:2016-04-12 00:41:59
【问题描述】:

我必须对以下内容进行简单的 CRC 检查:从端口获取 8 位输入,获取其 CRC 校验和值并输出。到目前为止,我可以获取输入并读取算法,因此我将 n - 1 个零添加到我的输入中,有效地使其大到足以成为 16 位。我也得到了它,我知道我在这里需要一个 XOR,因为我们在除法时做模 2。但是,我无法继续使用该算法,甚至不知道从哪里开始。

.MACRO INITSTACK
LDI         R16,        HIGH(RAMEND)
OUT         SPH,        R16
LDI         R16,        LOW(RAMEND)
OUT         SPL,        R16
.ENDMACRO

.MACRO LOADIO
LDI         R20,        @1
OUT         @0,         R20
.ENDMACRO

.include    "m128def.inc"
.EQU        ones = 0xFF             ; output
.EQU        zeros = 0x00            ; input
.EQU        CRC_CODE = 0x13         ; our CRC polynomial in binary (10011)
.DEF        INPUTREG = R16          ; input register
.DEF        CRC_RES = R17           ; Holds the CRC result (4 bits)
.DEF        OPREG1 = R18            ; temp operation register 1
.DEF        OPREG2 = R19            ; temp operation register 2
.DEF        OPREG3 = R20            ; temp operation register 3
.DEF        OPREG4 = R21            ; temp operation register 4
.DEF        OPREG5 = R22            ; temp operation register 5
.ORG        0x0000

main:

INITSTACK

; Modifies the INPUTREG
RCALL       TakeInput
RCALL       CreateCRC

LOADIO      DDRA,           ones
LOADIO      DDRB,           ones
OUT         PORTA,          CRC_RES

Stop:
NOP
JMP         Stop


TakeInput:
    LOADIO      DDRA,       zeros
    IN          INPUTREG,   PORTA
    CLR         XH
    MOV         XL,         INPUTREG
    LSL         XL          ; do a shift 4 times, for the 4 (5 - 1) zeros
    ROL         XH
    LSL         XL          ; do a shift 4 times, for the 4 (5 - 1) zeros
    ROL         XH
    LSL         XL          ; do a shift 4 times, for the 4 (5 - 1) zeros
    ROL         XH
    LSL         XL          ; do a shift 4 times, for the 4 (5 - 1) zeros
    ROL         XH
    RET

CreateCRC:
    LDI         OPREG1,     0x08        ; do shift 8 times
    LDI         OPREG2,     CRC_CODE    ; load the polynom
    LSL         OPREG2                  ; no need for 5th bit, we only do operation with lower 4 bits (CLC does XOR for the high bit we skipped)
    SWAP        OPREG2                  ; Swap nibbles, so the number has the bits we want at higher 4 bits
    CLZ
crc_loop:
    CLC
    ROL         INPUTREG
    DEC         OPREG1
    BREQ        crc_end                 ; if we did this 8 times, stop
    BRCC        crc_loop                ; no carry, then keep shifting, if its set we go to XOR
crc_do_xor:
    EOR         INPUTREG,   OPREG2
    JMP         crc_loop
crc_end:
    SWAP        INPUTREG                ; Swap the higher 4 bits to lower 4 bits
    MOV         CRC_RES,    INPUTREG
    RET

编辑:现在我得到的消息 1100 1111 的结果不正确,代码为 10011。输出应该是 1100,但我得到 1101。哪里可能出错?

【问题讨论】:

    标签: assembly avr crc atmega


    【解决方案1】:

    您的代码似乎还没有任何有用的东西。您需要考虑算法的工作原理,并决定使用所需字节的好方法。

    由于您的输入只是一个字节而不是流,我建议您使用该字节并执行 8 次移位。我建议你使用ROL,通过进位左移,和CLC,清除进位,以及XOR指令。

    这个想法是清除进位标志,然后向左旋转一位。如果设置了进位位,则需要与 00110000 进行异或指令。这是没有第一个 1 的多项式,左移。

    1) 11001111 CLC and ROL
    2) 10011110 with C=1, so do an XOR
       10101110 CLC and ROL
    3) 01011100 with C=1, so do an XOR
       01101100 CLC and ROL
    4) 11011000 with C=0, so don't XOR. 
                CLC and ROL
    5) 10110000 with C=1, so do an XOR
       01000000 CLC and ROL
    6) 10000000 with C=0, so don't XOR.
                CLC and ROL
    7) 00000000 with C=1, so do an XOR
       00110000 CLC and ROL
    8) 01100000 with C=0, so don't XOR. 
                CLC and ROL
    9) 11000000 The first four bits are the result. SWAP to get it to the right.
    

    编写一个执行此算法的循环,测试 C 位的分支。请注意,不需要直接使用多项式的高位。这意味着,如果设置了进位位,您只需对低位进行异或。 CLC 对进位位本身进行“异或”。

    【讨论】:

    • 我已经实现了这个算法,但我无法得到与你相同的输出 (1100)。由于某种原因,我得到了 1101。为什么会这样? (用我的代码更新了 OP)
    • 看起来我在第 5 步有错误。您的版本可能是正确的。尝试在更多示例上运行它(并确保比我做得更好!)
    猜你喜欢
    • 2013-02-25
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 2014-05-29
    相关资源
    最近更新 更多