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

How to Split the 16bit word?

Hi! i want to spilt the 16bit word into two 8bit words,
is there any key words for it. i use the p89V51 mcu and c language Cx51 keil compiler ver3.

regards,
K.T.Venkatesan.

Parents Reply Children
  • If you don't want shift and/or mask you can also use division and modulus

    e.g.,

      int Value;
      char Hi;
      char Lo;
    
      Value = 0x1234;
      Hi = Value/0x100;
      Lo = Value%0x100;
    

  • Ah yes - that makes four!

    Of course, division by a power of two is equivalent to shifting.

    I can't see any advantage of division & modulus over shift & mask - and there is the distinct possibility that it will be grossly inefficient if the compiler does actually implement it as the maths functions...

  • Hi! that's nice to use this method.Thank you matt and Neil.

  • Hi! sorry! u gave me three ways! but i thing the shifting is the most easy way.

  • The most "easy" way for the processor is to use the union - as this involves zero runtime processing.

    The other ways may or may not result in some runtime processing, depending on how smart the compiler and/or optimiser is.

    Whether any particular one is "easier" in terms of developer effort, maintenance, etc could be a subject for a very long and drawn-out discussion...

  • I'll start:

    "the union ... involves zero runtime processing."

    Apart from any possible overheads due to unaligned/misaligned access on some processors...?

  • "I can't see any advantage of division & modulus over shift & mask ..."

    Right-shifting an int having a negative value is implementation-defined, whereas div/mod are not.

  • in C
    extern the16
    extern hi8
    ext6ern lo8

    in assembler
    the16: ds 0
    hi8: ds 1
    lo8: ds 1

    this is breaking every 'rule' that exist but does allow simple addressing of all 3 entities.

    Now that we list methods, this one should be included.

    Erik

  • Using a union that way is a common misuse (of which I've been guilty of from time to time).

    The language standard says:

    6.7.2.1: "The value of at most one of the members can be stored in a union object at any time."

    6.2.6.1: "When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values."

    Annex J.1 "Unspecified behavior": "The value of a union member other than the last one stored into (6.2.6.1)."

  • Code generated by Keil C51 v8 (or v7) often benefits greatly from the union method.

    You can isolate the byte-order dependency with variant declarations controlled by a #define. In fact, if you're that concerned with portability, you're going to need a section of several such macros.

    typedef union
        {
        U16 u16;
    #if defined(CPU_ENDIAN_BIG)
        struct { U8 msb; U8 lsb; } bytes;
    #elif defined(CPU_ENDIAN_LITTLE)
        struct { U8 lsb; U8 msb; } bytes;
    #else
    #error Must define CPU_ENDIAN_BIG or _LITTLE
    #endif
        } MultiByte16;
    

    Bitfields can be assigned from the MSB or LSB at the implementation's whim, so you also need a "bitfield endianess" as well as a multi-byte-word endianenss.

  • Right-shifting an int having a negative value is implementation-defined, whereas div/mod are not.

    It would be nice if that were true, but actually this only holds if your compiler claims compliance to C99.

    In the original standardized version of the language, C90, which still has to be considered the default assumption for portable code, division of negative numbers is implementation-defined, too. (-1)/2 can yield either -1 or 0; (-1)%2 can be either -1 or 1.

  • Most 8 bit compiler know "int >> 8" is use the high byte.

    The best way would be try them all and look at the ASM generated. It is likely the compiler will create the same code for all of them.
    The results may vary with complier version.