Continue to Site

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.

  • 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.

Nibble Shift Code Help

Status
Not open for further replies.

Suraj143

Active Member
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:
        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
 
Optimize for size or speed? A small savings (perhaps 250+ cycles) could be had with minor changes...

More later (gotta run)...
Code:
        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:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top