This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Is this a C51 / uvision bug?

Hi all
Below is the result of some debugging. I have isolated some code from a bigger project and have put it into a stand-alone project.

I basically don't understand why I can do right bit-shifting and AND'ing on single line, when I can't do left bit-shifting and AND'ing on single line.

If it isn't a bug, then what have I missed?

I have included many comments to describe my problem

#include <ADUC832.H>
#include <string.h>

void main(void) {


char ascii[] = "MC";
unsigned char pdu[3];
int w=0, r=0, len;
char ch1, ch2, rr, rl;


 /*  This is what I want to do:

  while-loop run 1:
     1: Assign to var 'ch1':   ch1 = 'M' (= 0x4D = 0100 1101)
     2: Assign to var 'ch2':   ch2 = 'C' (= 0x43 = 0100 0011)
     3: Assign to var 'w'  :     w = 0
     4: OR together the following:
         ((ch1 >>(w%7))&0x7F) | ((ch2 <<(7-(w%7)))&0xFF);
     <=>     0100 1101        |       1000 0000
     <=>                  1100 1101
     <=>                     0xCD

  while-loop run 2:
     1: Assign to var 'ch1':   ch1 = 'C' (= 0x43 = 0100 0011)
     2: Assign to var 'ch2':   ch2 = 0x00
     3: Assign to var 'w'  :     w = 1
     4: OR together the following:
         ((ch1 >>(w%7))&0x7F) | ((ch2 <<(7-(w%7)))&0xFF);
     <=>     0010 0001        |       0000 0000
     <=>                  0010 0001
     <=>                     0x21

 */

len=strlen(ascii);

while (r<len) {

 // ------ First OR-part  -----------------------
 // -------Both versions below are OK  ----------

      // -- VER 1: OK
      //  ch1 = ascii[r];
      //  rr  = (w%7);
      //  ch1 = (ch1 >> rr) & 0x7F;

      // -- VER 2: OK
        ch1 = (ascii[r] >> (w%7)) & 0x7F;    // Bit-shifting and AND'ing
                                             // may be done in one line

 // ------  Second OR-part  -----------------------------
 //-------  Both versions below are NOT OK ??  ----------

      // -- VER 1: OK
        ch2 = ascii[r+1];
        rl = (7-(w%7));
        ch2 = (ch2 << rl) & ((char)0xFF);    // Bit shift and AND'ing can be
                                             // done in one line, IF type cast
                                             // is used - why?
      //  ch2 = ch2 & 0xFF;                  // If splitting into new line
                                             // type cast is not required?

      // -- VER 2: NOT OK
      //  ch2 = (ascii[r+1] << (7-(w%7))) & 0xFF;  // type cast doesn't help
      //  ch2 = ch2 & 0xFF;  // AND'ing must be on seperate line ?


    //----------------------------------------------------------------
    // IS THIS A BUG ??
    //----------------------------------------------------------------
    // Why can we bit-shift and do the AND'ing in a single line
    // for the first OR-part above, but cannot do it for the second
    // OR-part where bit-shifting and AND'ing must be on two seperate
    // lines ???
    //----------------------------------------------------------------

// ------ Do the actual OR'ing -------
        pdu[w]= (ch1 | ch2) ;

        if ((w%7)==6)
           r++;
        r++;
        w++;
    }
    pdu[w]=0; // terminator

    //----------------------------------------------------------------
    // Run to here in debugger and look at content of
    // local variable 'pdu'.
    // When using 'NOT OK' versions from above
    // pdu will contain {0x4D, 0x21, 0x00}
    // and not {0xCD, 0x21, 0x00} as the 'OK' versions
    // produce.
    //----------------------------------------------------------------

   while(1);

}

0