小问题:字节颠倒用什么方法最好?

[复制链接]
ifree64 发表于 2008-2-16 21:59 | 显示全部楼层

39L的方法问题在于如何实现你的几个交换?

AIRWILL 发表于 2008-2-17 22:16 | 显示全部楼层

看看,我写的 C51 程序

看看,我写的 C51 程序
unsigned char bitswap(unsigned char c) {
    unsigned char ch;
    CY = 1; ACC = c; CY = ACC & 0x80; 
    do { c = ACC;
        ACC = ch; CY = ACC & 1; 
        ch = ACC; CY = 0; 
        ACC = c;  CY = ACC & 0x80; 
    } while (ACC); 
    return ch;
}

总共才 17 bytes 的程序.
AIRWILL 发表于 2008-2-17 22:21 | 显示全部楼层

A51写得更短, 11 bytes,54 Clocks

?PR?_bitswap?CONVERT   SEGMENT CODE
    RSEG    ?PR?_bitswap?CONVERT 
    PUBLIC  _bitswap
_bitswap:        ; 11B, 54 Clock
    SETB    C
    CLR    A
    XCH    A,R7
    RLC    A    ; Bit 7
conver1:
    XCH    A,R7
    RRC    A
    XCH    A,R7
    RLC    A    ; Bit 6 ~ 0
    JNZ    conver1
    RET
赤铸 发表于 2008-2-17 22:51 | 显示全部楼层

硬件口线交换应该是最快的

如果要速度快,即使用查表法,也应该把表定义到 RAM 中(实际上是初始化时由 ROM 中读到 RAM)

我用过类似30楼的办法,只用一个口,不过后来看设计得比较失败,失去了速度快的优势,不如直接用两个口。

陈双君 发表于 2008-2-18 09:01 | 显示全部楼层

字节倒过来写就行了.

字节倒过来写就行了.
xxrrpp2000 发表于 2008-2-18 16:20 | 显示全部楼层

45楼说话真是幽默

赞一个。。。。。
yqblog 发表于 2008-2-21 10:33 | 显示全部楼层

51汇编"SWAP A"

ayb_ice 发表于 2008-2-21 11:00 | 显示全部楼层

48L

SWAP A是交换ACC的高低半字节,不符合要求。。。
gooog 发表于 2008-2-21 11:16 | 显示全部楼层

如果追求速度,一般要嵌入式汇编程序

带标志位的移位

rr r0
rl r1

rr r0
rl r1

rr r0
rl r1

rr r0
rl r1

rr r0
rl r1

rr r0
rl r1

rr r0
rl r1

rr r0
rl r1
有比着速度快的吗?



dengm 发表于 2008-2-21 13:34 | 显示全部楼层

Bits SWAP 13 CYS 51 ASM

         SWAP A       ; C 32107654
         MOV C, ACC.6 ; 2 32107654
         RRC C        ; 4 23210765
         MOV ACC.5,C  ; 4 23410765
         MOV C, ACC.4 ; 1 23410765
         RRC A        ; 5 12341076
         MOV ACC.3,C  ; 5 12345076
         MOV C, ACC.2 ; 0 12345076
         RRC A        ; 6 01234507
         MOV ACC.1,C  ; 6 01234567
ddb_21ic 发表于 2008-2-21 16:08 | 显示全部楼层

顶44L,我刚想说这个办法

xhtxzxw 发表于 2008-3-2 18:02 | 显示全部楼层

嘿嘿

这个帖子还要玩一玩的!~
unsigned char bitrev(unsigned char x)
{
  unsigned char bdata before_rev = x;
  unsigned char bdata after_rev;

  sbit bfrBit0 = before_rev^0;
  sbit bfrBit1 = before_rev^1;
  sbit bfrBit2 = before_rev^2;
  sbit bfrBit3 = before_rev^3;
  sbit bfrBit4 = before_rev^4;
  sbit bfrBit5 = before_rev^5;
  sbit bfrBit6 = before_rev^6;
  sbit bfrBit7 = before_rev^7;

  sbit afrBit0 = after_rev^0;
  sbit afrBit1 = after_rev^1;
  sbit afrBit2 = after_rev^2;
  sbit afrBit3 = after_rev^3;
  sbit afrBit4 = after_rev^4;
  sbit afrBit5 = after_rev^5;
  sbit afrBit6 = after_rev^6;
  sbit afrBit7 = after_rev^7;

  afrBit0 = bfrBit7;
  afrBit1 = bfrBit6;
  afrBit2 = bfrBit5;
  afrBit3 = bfrBit4;
  afrBit4 = bfrBit3;
  afrBit5 = bfrBit2;
  afrBit6 = bfrBit1;
  afrBit7 = bfrBit0;
  
  return(after_rev);
}
xwj 发表于 2008-3-3 18:26 | 显示全部楼层

说了:1、硬件读最快;2、查表第二

其他的,再快再快也要慢得多
machunshui 发表于 2008-3-3 21:51 | 显示全部楼层

4字节,查表算法

如果嫌16字节太多,根据4位位反转统计规律,
可以用以下4字节查表法.

Table[4] = {0,8,4,12};

High = X>>4;
Low = ( X & 0xf );

if(High < 4)       { High = Table[High]; break;}
else if(High < 8)  { High = Table[High-4]+2; break;}
else if(High < 12) { High = Table[High-8]+1; break;}
else                 High = Table[High-12]+3;

if(Low < 4)       { High = Table[Low]; break;}
else if(Low < 8)  { High = Table[Low-4]+2; break;}
else if(Low < 12) { High = Table[Low-8]+1; break;}
else                High = Table[Low-12]+3;

X = (Low<<4) + High;
machunshui 发表于 2008-3-3 22:05 | 显示全部楼层

当然直接16字节查表是最好的折中

unsigned char Table[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};

//X为待反转的字节
High = Table[X>>4];
Low = Table[X & 0xf];

X = (Low<<4) + High;

除了硬件和不怕浪费空间的256字节查表外,
没有比这个更加快的了.
ayb_ice 发表于 2008-3-4 11:31 | 显示全部楼层

回53楼

bdata变量必须是全局的才行...
Anymcu 发表于 2008-3-4 15:50 | 显示全部楼层

C51的,17cycles

uchar bdata Tmpbyte;
sbit Tmpbyte0 = Tmpbyte^0;
sbit Tmpbyte1 = Tmpbyte^1;
sbit Tmpbyte2 = Tmpbyte^2;
sbit Tmpbyte3 = Tmpbyte^3;
sbit Tmpbyte4 = Tmpbyte^4;
sbit Tmpbyte5 = Tmpbyte^5;
sbit Tmpbyte6 = Tmpbyte^6;
sbit Tmpbyte7 = Tmpbyte^7;

unsigned char bitrev(unsigned char Revdat)
{
  ACC=Revdat;       //1
  Tmpbyte=ACC;      //1
  CY=Tmpbyte6;      //1
  _rrca_();         //1
  CY=Tmpbyte5;      //1
  _rrca_();         //1
  CY=Tmpbyte4;      //1
  _rrca_();         //1
  CY=Tmpbyte3;      //1
  _rrca_();         //1
  CY=Tmpbyte2;      //1
  _rrca_();         //1
  CY=Tmpbyte1;      //1
  _rrca_();         //1
  CY=Tmpbyte0;      //1
  _rrca_();         //1
  return(ACC);      //1
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部