AVR C中字符数组的按位移位

时间:2015-10-08 18:35:42

标签: c arrays avr bit-shift

最初我需要连续发送和接收一些数据。数据包长度为48位。 对于较短的数据包(32位),我可以这样做:

unsigned long data=0x12345678;

for(i=0;i<32;i++){
  if(data & 0x80000000)
    setb_MOD;
  else
    clrb_MOD;
  data <<= 1;
}

这段代码编译真让我高兴:

        code<<=1;
  ac:   88 0f           add r24, r24
  ae:   99 1f           adc r25, r25
  b0:   aa 1f           adc r26, r26
  b2:   bb 1f           adc r27, r27
  b4:   80 93 63 00     sts 0x0063, r24
  b8:   90 93 64 00     sts 0x0064, r25
  bc:   a0 93 65 00     sts 0x0065, r26
  c0:   b0 93 66 00     sts 0x0066, r27

在我需要扩展数据包(到48位)之后,我面临需要移位数组:

unsigned char data[6]={0x12,0x34,0x56,0x78,0xAB,0xCD};

for(i=0;i<48;i++){
  if(data[5] & 0x80)
    setb_MOD;
  else
    clrb_MOD;
  for(j=5;j>0;j--){
    data[j]<<=1;
    if(data[j-1] & 0x80)
      data[j]+=1;
  }
  data[0] <<= 1;
}

编译后的代码稍微取决于优化设置,但通常是按照我在C中的命令执行:

        for(j=5;j>0;j--){
            code[j]<<=1;
  a8:   82 91           ld  r24, -Z
  aa:   88 0f           add r24, r24
  ac:   80 83           st  Z, r24
            if(code[j-1]&0x80)
  ae:   9e 91           ld  r25, -X
  b0:   97 fd           sbrc    r25, 7
  b2:   13 c0           rjmp    .+38        ; 0xda <__vector_2+0x74>
            clrb_MOD;
        }
        else{
            setb_MOD;
        }
        for(j=5;j>0;j--){
  b4:   80 e0           ldi r24, 0x00   ; 0
  b6:   a3 36           cpi r26, 0x63   ; 99
  b8:   b8 07           cpc r27, r24
  ba:   b1 f7           brne    .-20        ; 0xa8 <__vector_2+0x42>
            code[j]<<=1;
            if(code[j-1]&0x80)
                code[j]+=1;
        }

正如您所看到的那样,没有明显的(人为)解决方案来在字节之后移位数组字节。

我想跳过内联汇编程序的注入,因为我并没有真正管理这种技术而且我真的不明白如何解决Asm中的C变量问题。还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

如果您知道您的输入少于64位,您可以执行类似的操作(假设stdint.h可用,否则转换为unsigned long long等):

union BitShifter
{
   uint64_t u64;
   uint32_t u32[2];
   uint16_t u16[4];
   uint8_t  u8[8];
};

union BitShifter MyBitshifter;

MyBitShifter.u64 <<= 1;

编译器应该使用最好的指令来完成它(可能是两个32位移位和一些其他逻辑来从一个字到另一个字。当然,后端可能是懒惰的,并将其作为字节... < / p>

根据AVR的字节顺序,您必须按正确的顺序将字节调整为正确的传出位顺序。