Rotate/Reverse 位在 16 位数中的位置

Rotate/Reverse positions of bits in 16-bit number

我正在使用 8051 微控制器并找到了一种更好的方法来将数据传输到移位寄存器。到目前为止,我使用的是位碰撞技术,从最高有效位开始一次一位地移出位。新方法是用硬件串口完成的,但是我了解到数据是从最低有效位开始移出的(完全相反的方向)。

为了遵守,我必须重新整理我的数据。目前,有问题的数据大小是 16 位,我可能还有一个 24 位的数据大小需要转换。

当我仅转换 8 位大小时,我使用了仅 256 字节的查找 table。这大约是我可用代码的 1/16 space,因为我将所有代码塞进了 AT89C4051 micro。

如果我尝试使用 16 位大小进行相同操作,我可能会超过限制,因为 256 乘以 256 等于 65K(查找 table 需要多大?)

所以我正在寻找一种高速算法来很好地完成这项工作。

这是我到目前为止在 8051 代码中提出的,我认为它有点太慢且难以维护,但它似乎可以完成工作:

;DPTR = 16-bit number to convert

mov R7,#10h ;16 bits
nextbit:
mov A,DPH
rrc A
mov DPH,A
mov A,DPL
rrc A
mov DPL,A
mov A,R2
rlc A
mov R2,A
mov A,R3
rlc A
mov R3,A
djnz R7,nextbit
mov DPH,R3
mov DPL,R2

任何人都可以指出我可以使用的更快的代码甚至更好的算法,而不是一个一个地移入移出位吗?

从视觉上看,这就是我尝试对二进制位进行排序的方式。假设"a"需要从16位数字的最低位到最高位,"b"需要从第二低位到第二高位,依此类推。这是示例:

 ponmlkji:hgfedcba -> abcdefgh:ijklmnop

至少你可以在每个循环迭代中传输两位,这样循环计数减半:

mov R7,#8 
nextbit:

  mov A,DPH
  rrc A
  mov DPH,A
  mov A,R2 ;R2 will become the lowbyte of the result
  rlc A 
  mov R2,A

  mov A,DPL
  rrc A
  mov DPL,A
  mov A,R3
  rlc A
  mov R3,A

djnz R7,nextbit
mov DPH,R3
mov DPL,R2

或查找 table 有 256 个条目(256 字节):

mov R2, DPH
mov A,  DPL
mov dptr, LookupTable256
movc a,@a+dptr ;Translate lowbyte into hibyte of result
xch A, R2
movc a,@a+dptr
;lowbyte in a, hibyte in R2

这里是一个半字节翻译版本,使用查找-table,只有 16 个条目:

mov R2, DPH
mov R3, DPL
mov dptr, LookupTable16

mov a, R3
and a, #0Fh    ;=Nibble0
movc a,@a+dptr ;Translate
swap           ;swap nibbles
xch A, R3      ; store result nibble 3 
swap 
and a, #0Fh    ;=Nibble1
movc a,@a+dptr ;Translate
orl AR3, A     ;R3=Result nibbles 2+3

mov a, R2
and a, #0Fh    ;=Nibble2
movc a,@a+dptr ;Translate
swap 
xch A, R2      ; store result nibble 1 
swap 
and a, #0Fh    ;=Nibble3
movc a,@a+dptr ;Translate
orl A, R2       ;A=Result nibbles 0+1