title: Bitwise shift of an array of chars in AVR C
body: <p>Initially I need to send and receive serially some data. The packet length is 48 bits.
  For shorter packets (32 bits) I could do something like that:</p>
  
  <pre><code>unsigned long data=0x12345678;
  
  for(i=0;i&lt;32;i++){
    if(data &amp; 0x80000000)
      setb_MOD;
    else
      clrb_MOD;
    data &lt;&lt;= 1;
  }
  </code></pre>
  
  <p>This code compilation is really pleasing me:</p>
  
  <pre><code>        code&lt;&lt;=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
  </code></pre>
  
  <p>After I needed to extend the packet (to 48 bits) I faced with the need to shift an array:</p>
  
  <pre><code>unsigned char data[6]={0x12,0x34,0x56,0x78,0xAB,0xCD};
  
  for(i=0;i&lt;48;i++){
    if(data[5] &amp; 0x80)
      setb_MOD;
    else
      clrb_MOD;
    for(j=5;j&gt;0;j--){
      data[j]&lt;&lt;=1;
      if(data[j-1] &amp; 0x80)
        data[j]+=1;
    }
    data[0] &lt;&lt;= 1;
  }
  </code></pre>
  
  <p>The compilled code is slightly depends on an optimization settings but generally it is doing what I commanded in C:</p>
  
  <pre><code>        for(j=5;j&gt;0;j--){
              code[j]&lt;&lt;=1;
    a8:   82 91           ld  r24, -Z
    aa:   88 0f           add r24, r24
    ac:   80 83           st  Z, r24
              if(code[j-1]&amp;0x80)
    ae:   9e 91           ld  r25, -X
    b0:   97 fd           sbrc    r25, 7
    b2:   13 c0           rjmp    .+38        ; 0xda &lt;__vector_2+0x74&gt;
              clrb_MOD;
          }
          else{
              setb_MOD;
          }
          for(j=5;j&gt;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 &lt;__vector_2+0x42&gt;
              code[j]&lt;&lt;=1;
              if(code[j-1]&amp;0x80)
                  code[j]+=1;
          }
  </code></pre>
  
  <p>As you can see there is no obvious (for a human) solution to shift an array byte after byte.</p>
  
  <p>I'd like to skip injection of inline assembler as I don't really manage this technique and I don't really understand how do I address C variables in Asm. Is there any alternatives?</p>