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

BUG with bits in integer variable

There is a BUG in the compilation of a bit definition:

unsigned int bdata my_int;
sbit bit15 = my_int ^ 15;
sbit bit7 = my_int ^ 7;

void main()
{
  my_int = 0x8000;

  if(bit15)
  {
    // Here we shall not appear,as compiller
    // will be erroneous to check 7-bit of
    // a variable my_int instead of 15-bit
    // (as this variable place in memory in
    // little endian order)
    // ...
  }

  if(bit7)
  {
    // oops! we here!
    // ...
  }
}
This is a BUG! Please correct. Thanx.

  • I have found such note in the C51 manual:
    -------------------------------------------
    "The sbit data type uses the specified variable as a base address and adds the bit
    position to obtain a physical bit address. Physical bit addresses are not equivalent to logical bit positions for certain data types. Physical bit position 0 refers to bit position 0 of the first byte. Physical bit position 8 refers to bit position 0 of the second byte. Because int variables are stored high-byte first, bit 0 of the integer is located in bit position 0 of the second byte. This is physical bit position 8 when accessed using an sbit data type."
    -------------------------------------------
    That only people will not think up to explain the absurds!

  • That only people will not think up to explain the absurds!
    it is crystal clear from your post that you have refused to even glance at the '51 architecture. Had you done so, the explanation would have been crystal clear.

    Well, since you refuse to study the '51 architecture, one comment

    Good luck, you will need it

    Erik

    for your sake I hope I'm wrong.

  • This is why there are also two ways people like to number bits (bit endianness) as well as bytes (byte endianness). Whichever method you pick, someone will be unhappy.

    Intel ordained the hardware's method of number bits and mapping bit addresses to bytes.

    Either the multi-byte sbit type has non-continguous bits when numbered sequentially, the bit numbers don't match order of physical bit addresses, or the sbit bit numbers won't match the number of shifts needed with the shift operators to get to that bit position.

  • "the bible states:
    One way is to refer to their address (i.e., 0-7FH). The other way is with reference to bytes 20H to 2FH. Thus, bits 0-7 can also be referred to as bits 20.0-20.7, and bits 8-FH are the same as 21.0-21.7, and so on.

    Erik

  • Do not stir bosh. Speak to the point. I have studied '51 architecture at once as soon as it has appeared. As it is the one-byte controller all other "wide" types of data are added by C-compiler. So C-compiler knows as data place in memory and it can take the necessary byte and to analyse necessary bit. I have declared the integer (16-bits) and I want at it 14-th bit. Instead of it I for some reason should read any ridiculous explanations and specify 6-bats. Unless it not absurdity?

  • Bits in data of any width are always 0 - LSB, etc. up to MSB. And realization in hardware is only consequence. So attempt to invent something other looks absurdity. And to speak about linear addressing in general it is impossible - you in fact cannot declare a array of sbit[].

  • hi,

    unsigned int bdata my_int;
    sbit bit15 = my_int ^ 15;
    sbit bit7 = my_int ^ 7;
    

    So what it does:

    - first line allocates two bytes of memory inside bit-addressable memory space to place integer number there and names variable as my_int;
    - second and third lines declare two variables: bit7 and bit15. These variables are defined as 7th and 15th bits of bit-addressable memory space related from address where variable my_int has been placed. Important note: lines like
    bitX = variable ^ X;
    HAVE NOTHING with the variable; they are related to the address where the variable is placed at. Due Keil uses big-endian storing format so it holds MSB of integer firstly then LSB.

    Bits in data of any width are always 0 - LSB, etc. up to MSB.

    The native C does not support bit variables at all. ANSI C supports bit-fields only. Such questions as bit-field placement, bits' order and how many bytes are utilized per bitfield - are not defined by ANSI C. It says: "compiler-dependence, read its manual".

    Now come back to your code. For me it is clean and should be translated to:
    void main()
    {
      my_int = 0x8000;
    
      if((my_int & 0x8000) != 0)  // check for bit 15
      {
      }
      if((my_int & 0x0080) != 0) // check bit 7
      {
      }
    }
    
    Regards,
    Oleg
    

  • Hi.

    Keil realy transletes my code to this:

    unsigned int bdata my_int;
    sbit bit15 = my_int ^ 15;
    sbit bit7 = my_int ^ 7;
    
    void main()
    {
      my_int = 0x8000;
    
      if((my_int & 0x0080) != 0)  // <- if(bit15)
      {
      }
      if((my_int & 0x8000) != 0)  // <- if(bit7)
      {
      }
    }
    
    But the code will be translate correctly if I at once shall write so (without "sbit x=y^n"):
    void main()
    {
      my_int = 0x8000;
    
      if((my_int & 0x8000) != 0)  // check bit 15
      {
      }
      if((my_int & 0x0080) != 0)  // check bit 7
      {
      }
    }
    

  • sbit bit15 = my_int ^ 15;

    you can only use sbit for bit addressable bytes

    Erik

  • Do you read Cx51 User's Guide? Probably, no. Here a part from it:
    --------------------------------------------
    Bit-Addressable Objects

    Bit-addressable objects are objects that may be addressed as words or as bits. Only data objects that occupy the bit-addressable area of the 8051 internal memory fall into this category.

    The Cx51 Compiler places variables declared with the bdata memory type into the bit-addressable area. Furthermore, variables declared with the bdata memory type must be global (declared outside the scope of a function). You may declare these variables as shown below:

    int bdata ibase;        /* Bit-addressable int */
    
    char bdata bary [4];    /* Bit-addressable array */
    
    The variables ibase and bary are bit-addressable. Therefore, the individual bits of these variables may be directly accessed and modified. Use the sbit keyword to declare new variables that access the bits of bdata variables. For example:
    sbit mybit0 = ibase ^ 0;      /* bit 0 of ibase */
    sbit mybit15 = ibase ^ 15;    /* bit 15 of ibase */
    
    sbit Ary07 = bary[0] ^ 7;     /* bit 7 of bary[0] */
    sbit Ary37 = bary[3] ^ 7;     /* bit 7 of bary[3] */
    
    The above example represents declarations, not assignments to the bits of the ibase and bary bdata variables. The expression following the carat symbol ('^') in the example specifies the position of the bit to access with this declaration. This expression must be a constant value. The range depends on the type of the base variable included in the declaration. The range is 0-7 for char and unsigned char, 0-15 for int, unsigned int, short, and unsigned short, and 0-31 for long and unsigned long.

  • Isn't it interesting that when the software does not behave in the way someone want it to do (forget what the manual says) it is always a BUG. Never a "problem" "possible misunderstanding" no absolutely a BUG!

    Erik