This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

reduce code size

hello,

I have to perform this calculation for huge number of data,

so I have to reduce number of assembly instruction as much as possible

here the code

MOV AR6,*XAR4++ ; AR6 = *array++

AND AR6,#0xFF ; AR6 = AR6 & 0xFF

XOR AL,AR6 ; crc ^= AR6

I have to XOR low byte of memory content at XAR4 address

so I move *XAR4 to AR6, mask high byte and subsequently XOR

because there is not this operand/code combination

 

XORB AL,*XAR4++

Has someone any Idea to reduce this code ?

thankyou

  • AND AH,*XAR4++,#0x00FF
    XOR AL,@AH
    Should take 2 cycles per byte
  • thank you for the solution but I have to put all code

    because AH is already used for byte counting ...

    the code perform CRC16 calculation of an array of bytes

    ; Prototype

    ; Uint16 CRC16(Uint8* array, Uint16 seed, int size);

    ; AL 16b CRC16(XAR4 32b, AL 16b, AH 16b );

    _CRC16:

    MOVZ AR5,AL ; AR5 = seed

    MOV @AL,#0xFFFF ; AL = crc0

    _LOOP:

    MOV AR6,*XAR4++ ; AR6 = *array++

    AND AR6,#0xFF ; AR6 = AR6 & 0xFF

    XOR AL,AR6 ; crc ^= AR6

    ; x8

    ; crc >> 1

    ; if(CARRY) crc ^= seed

    LSR AL,1 ; 1

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 2

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 3

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 4

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 5

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 6

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 7

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 8

    SB +2,NC

    XOR AL,AR5

    SUBB AH,#1 ; size--

    SBF _LOOP,NEQ ; while(size>0)

    LRETR

  • ok, using your suggest

    I move AH in AR6 before doing loop

    and I use 

    AND AH,*XAR4++,#0xFF

    instruction.

    Here the code

     

    ; Uint16 CRC16(Uint8* array, Uint16 seed, int size);

    ; AL 16b CRC16(XAR4 32b, AL 16b, AH 16b );

    _CRC16:

    MOVZ AR5,AL ; AR5 = seed

    MOVZ AR6,AH ; AR6 = size

    MOV @AL,#0xFFFF ; AL = crc0 (0xFFFF)

    _LOOP:

    AND AH,*XAR4++,#0xFF ; AH = lsb(*array++) & 0xFF

    XOR AL,AH ; crc ^= lsb(*array++)

    ; x8

    ; crc >> 1

    ; if(CARRY) crc ^= seed

    LSR AL,1 ; 1

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 2

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 3

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 4

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 5

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 6

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 7

    SB +2,NC

    XOR AL,AR5

    LSR AL,1 ; 8

    SB +2,NC

    XOR AL,AR5

    SUB AR6,#1 ; size--

    SBF _LOOP,NEQ ; while(size>0)

    LRETR

     

  • Mauro,
    what device are you using by the way? What is the CRC polynomial?

    If you want to count a loop, you have the following instruction which can use any of the AR registers as a counter:

    BANZ _LOOP,ARn--

    This frees up the AH register.

    Why don't you try the following code (free of charge) :-)

    _CRC16:
    MOVZ AR5,@AL ; AR5 = seed
    MOV @AL,#0xFFFF ; AL = crc0 = 0
    MOV @AR6,#LOOP_COUNT
    _LOOP:
    AND AH,*XAR4++,#0x00FF
    XOR AL,@AH

    LSR AL,#1
    MOV AH,@AR5
    MOVB AH,#0x00,NC
    XOR AL,@AH

    LSR AL,#1
    MOV AH,@AR5
    MOVB AH,#0x00,NC
    XOR AL,@AH

    ....
    ....

    LSR AL,#1
    MOV AH,@AR5
    MOVB AH,#0x00,NC
    XOR AL,@AH

    BANZ _LOOP,AR6--
    LRETR

    Cheers,
    Alex T.
  • seed is 0xa001,

    thank you for the solution

    MOV AH,@AR5
    MOVB AH,#0x00,NC

    take 2 cycle instead 7/4 of

    SB +2,NC

    so code is VERY more fast
  • it takes 11 + 39 x size cycles