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

bit ops: why does this work?

from reading the docs, i cannot understand why this code __works__?:

union _word {
  uint word;
  struct {
    uchar low;
    uchar hi;
  } bytes;
};

   static bdata uint bstate = 0;


  sbit sb_AC_IS_OK = bstate ^ 0;
  sbit sb_DC_TROUBLE = bstate ^ 1;
  sbit sb_LIGHTS_FAILED = bstate ^ 2;
  sbit sb_NEEDS_LVD = bstate ^ 3;
  sbit sb_BUTTON_PRESSED = bstate ^ 4;
  sbit sb_CIRCUIT_OKAY = bstate ^ 5;
  sbit sb_CLK_TICK = bstate ^ 6;
  sbit sb_TEST_MODE = bstate ^ 7;
  sbit sb_FIRE_ALARM_ACTIVE = bstate ^ 8;
  sbit sb_LAMP_CALIBRATED = bstate ^ 9;
  sbit sb_BAT_CONX_OK = bstate ^ 11;

BIT_OUT hw__get_bit_in_word(unsigned int word, uchar bitnum)
{
  union _word tmp_word;
  tmp_word.word = _iror_(word, bitnum);
  return   tmp_word.bytes.low & 1  ;
}

state_t hw__state_of(cmp_t cmp)
{
  return hw__get_bit_in_word(bstate, cmp);
}

i do not understand why hw__state_of() works correctly? according to docs, i have the byte order of the struct reversed. so why when i go tmp_word.bytes.low & 1 do i get the correct bit?

signed 'dazed and confused'

Parents Reply Children
  • You just need to read the docs more closely. There's a sneaky little comment on page 180 (of my version) at the end of the "Bit Types" section:

    "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."

    So, yes, you do have the byte order of your union reversed with respect to the byte order of the U16 (which is stored big endian). But the bits in a multi-byte bdata type are arranged in a little-endian fashion.

    FWIW, the generic pointer format is also "little endian"; its low / high format is the reverse of the 16-bit pointer format in registers. Perhaps consistency is also the hobgoblin of small microcontrollers.