1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Nibble Shift Code Help

Discussion in 'Microcontrollers' started by Suraj143, Aug 10, 2018 at 3:03 AM.

  1. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,637
    Likes:
    2
    Location:
    South Mald Isld
    I have a 32 byte array & I want to shift its nibbles separately.
    Means when I call the subroutine, it will shift the upper nibbles of the array left and shift their lower nibbles right.

    Did a code but seems likes its too long :( need to optimize

    Thanks

    Code (text):

            cblock        30h
            C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16
            C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32        ;4Fh last byte
            endc      
                   
    Shift_Left                movlw    .32
                            movwf    Byte_Count
                            movlw    30h
                            movwf    FSR                      
                            movf    INDF,W
                            movwf    Copy_Last        ; save 1st byte                      
                           
    Shift_Upper_Left        movf    INDF,W
                            andlw    b'00001111'        ; clear the upper nibble
                            movwf    INDF
                            incf    FSR,F
                            movf    INDF,W
                            andlw    b'11110000'        ; only move upper nibble
                            decf    FSR,F
                            iorwf    INDF,F
                            incf    FSR,F
                            decfsz    Byte_Count,F
                            goto    Shift_Upper_Left
                            movf    C32,W            ; last byte
                            andlw    b'00001111'
                            movwf    C32
                            movf    Copy_Last,W
                            iorwf    C32,F
    ;------------------------------------------------                      
    Shift_Right                movlw    4Fh
                            movwf    FSR
                            movlw    .32
                            movwf    Byte_Count
                            movf    INDF,W
                            movwf    Copy_Last        ; save 1st byte  
                           
    Shift_Lower_Right        movf    INDF,W
                            andlw    b'11110000'        ; clear the lower nibble
                            movwf    INDF
                            decf    FSR,F
                            movf    INDF,W
                            andlw    b'00001111'        ; keep only lower nibble
                            incf    FSR,F
                            iorwf    INDF,F
                            decf    FSR,F
                            decfsz    Byte_Count,F
                            goto    Shift_Lower_Right
                            movf    C1,W            ; last byte
                            andlw    b'00001111'
                            movwf    C1
                            movf    Copy_Last,W
                            iorwf    C1,F
                            return
     
  2. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,711
    Likes:
    129
    Location:
    Michigan, USA
    Optimize for size or speed? A small savings (perhaps 250+ cycles) could be had with minor changes...

    More later (gotta run)...
    Code (asm):

            radix dec
    ;
    ;  shift hi nibble to the left
    ;
            movlw   32              ;
            movwf   count           ;
            addlw   C1              ;
            movwf   FSR             ; FSR = address C1+32
            movf    C1,W            ; copy C[0] to C[31]
    sl
            decf    FSR,F           ;
            xorwf   INDF,W          ; exchange wreg and INDF
            andlw   0xF0            ; hi nibble only
            xorwf   INDF,F          ;  "
            xorwf   INDF,W          ;  "
            decfsz  count,F         ; done? yes, skip, else
            goto    sl              ;
    ;
    ;  shift lo nibble to the right
    ;
            bsf     count,5         ; reset count = 32
            movf    c32,W           ; copy C[31] to C[0]
    sr
            xorwf   INDF,W          ; exchange wreg and INDF
            andlw   0x0F            ; lo nibble only
            xorwf   INDF,F          ;  "
            xorwf   INDF,W          ;  "
            incf    FSR,F           ;
            decfsz  count,F         ; done? yes, skip, else
            goto    sr              ;
            return                  ;
     
     
    Last edited: Aug 11, 2018 at 1:42 PM
    • Thanks Thanks x 1
  3. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,637
    Likes:
    2
    Location:
    South Mald Isld
    What a piece of code. Works superbly.

    Thank you very much.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice