如何在 pic 汇编中操作单个寄存器以创建字节顺序交换效果?

How to manipulate single register to create endianness swap effect in pic assembly?

我必须使用 pic 汇编代码生成以下结果:

;msb::lsb
7,6,5,4,3,2,1,0 ;These bits in single register
;Result should be following:
0,1,2,3,4,5,6,7

其中每个数字代表位。这几乎改变了寄存器的字节顺序。这种寄存器操作如何在 8 位 pic 汇编中实现?我正在尝试通过使用内联汇编来优化我的 C 代码,并将输入值放入寄存器中。我读过 swapf 指令,但它会导致如下错误位:3,2,1,0,7,6,5,4 我用的图片是PIC16F887

执行此操作的最佳方法取决于您的特定 8 位 PIC 架构(PIC16、traditional/enhanced PIC18 等)以及您愿意在其上花费的 ROM/RAM 数量。

下面是我未经测试的尝试,尝试使用 ROM 表实现 dwelch 建议的 PIC16 交换方法。它应该在 13 个指令周期内完成:

        ;Reverse nybbles of W separately and merge the results
        MOVWF   tmp1
        CALL    nybble
        MOVWF   tmp2
        SWAPF   tmp1,W
        CALL    nybble
        SWAPF   WREG
        ORF     tmp2,W

        ;Helper function reversing an LSD nybble of W via a table.
        ;The table must _not_ cross a 256-word page!
nybble: ANDLW   0x0F
        ADDWF   PCL
        RETLW   b'0000 : RETLW  b'1000
        RETLW   b'0100 : RETLW  b'1100
        RETLW   b'0010 : RETLW  b'1010
        RETLW   b'0110 : RETLW  b'1110
        RETLW   b'0001 : RETLW  b'1001
        RETLW   b'0101 : RETLW  b'1101
        RETLW   b'0011 : RETLW  b'1011
        RETLW   b'0111 : RETLW  b'1111

如果您优化的是大小而不是速度,您可以尝试在任一方向上通过一对累加器进行移位的直接方法:

        SETC                ;Wind-in the loop condition sentinel
        RLF     input
loop:   RRF     output      ;Go for it!
        RLF     input
        BNZ     loop

循环通过用零缓慢填充 input 来工作。一旦哨兵转出进位,并且 input 为零,循环终止。