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
我正在使用 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