Thread: little endian query

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    44

    little endian query

    hi,
    I wrote a code to check the endianess of my PC. this is a core I-5, so 8086 based
    processor, should be little endian.I am using Visual Studio 2010.

    The data i have is 0x0100 or 256d. in little endian, lower address should store
    LSByte or 0x00 and higher address should have MSbyte as 0x01. that i verified
    by the code below.

    Code:
    #include <stdio.h>
    
    int main()
    {
       short int a= 256;      // 0x0100
       unsigned char *p = (unsigned char *)&a;
       unsigned char ch[3] = "AB";  //0x410x42
       unsigned char *p1= ch;
    
       printf (" *p= %x and *(p+1)=%x\n ", *p,*(p+1));
       a= a<<7;    // to confirm the little endian memory organization
       printf (" *p= %x and *(p+1)=%x\n ", *p,*(p+1));
       
       //** repeat for the string**//
       printf (" *p1= %x and *(p1+1)=%x\n ", *p1,*(p1+1));
       ch[0]= ch[0]<<7;
       ch[1]= ch[1]<<7;
       printf (" *p1= %x and *(p1+1)=%x\n ", *p1,*(p1+1));
    
    
    }
    I have following questions
    1) as seen in the attachment, memory at address 0x0033FEA4 (of variable a) shows 0x0100 which means address that grows from left to right. is this the way its actually stored in the memory?or it is that variable a is stored other way round but Visual Studio shows it like this
    little endian query-figure1-png
    so its just a different visualization but not actual hardware memory organization?

    2) in case of string ch= "AB" which is 0x41 and 0x42, following the same analogy,
    ch[0] or lower address in little endianness should have LSB as 'B' or 0x42 , and higher address should have MSB as 'A' or 0x41. however, what is see in the memory window is opposite as shown below
    little endian query-figure2-png

    why?
    I found a reference to this in the wikipedia article at
    http://en.wikipedia.org/wiki/Endiann
    ess
    and is shown in figure 3.
    little endian query-figure3-jpg

    these results are also given in the output window whose snapshot is given in figure 4.
    little endian query-figure4-png

    thanks
    sedy

  2. #2
    Registered User gardhr's Avatar
    Join Date
    Apr 2011
    Posts
    151
    Endian-ness applies only to native integral types larger than a byte. Not floating point numbers, nor arrays of any type, etc.

    I'm not sure why you're shifting the values of a byte array either - were you hoping that the result would somehow "migrate" through the array? It just doesn't work that way.

    Anyway, the Visual Studio screenshot shows the low-byte of 'a' (0x00) stored at address 0x0033FEA4 and the high-byte (0x01) at 0x0033FEA5, which is exactly what you'd expect to see on a little-endian machine.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by sed_y View Post
    1) as seen in the attachment, memory at address 0x0033FEA4 (of variable a) shows 0x0100 which means address that grows from left to right. is this the way its actually stored in the memory?or it is that variable a is stored other way round but Visual Studio shows it like this
    To see how variable "a" is laid out in memory you'd need to print out the contents of that location a char at a time, tho' it'd look like:
    Code:
    li'l endian:  0x0010
    big endian:   0x0100
    Quote Originally Posted by sed_y View Post
    so its just a different visualization but not actual hardware memory organization?
    Yep!
    Quote Originally Posted by sed_y View Post
    2) in case of string ch= "AB" which is 0x41 and 0x42, following the same analogy,
    ch[0] or lower address in little endianness should have LSB as 'B' or 0x42 , and higher address should have MSB as 'A' or 0x41. however, what is see in the memory window is opposite as shown below


    why?
    Complex data types like arrays, structs, etc. have no endianness as a whole but their elements do. So for string "AB" or "\x41\x42", the first character 'A' would be stored in memory as:
    Code:
    li'l endian:   10000010
    big endian:    01000001
    Last edited by itCbitC; 08-31-2011 at 10:53 PM.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by gardhr View Post
    Endian-ness applies only to native integral types larger than a byte. Not floating point numbers, nor arrays of any type, etc.
    IBTD, endianness applies to all types, be they char, short, integer, float or double. For the aggregate types (like arrays, structs etc.) it applies to the individual elements but not to the aggregate as a whole.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by itCbitC View Post
    IBTD, endianness applies to all types, be they char, short, integer, float or double. For the aggregate types (like arrays, structs etc.) it applies to the individual elements but not to the aggregate as a whole.
    So close...


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by quzah View Post
    So close...


    Quzah.
    lol?

  7. #7
    Registered User
    Join Date
    May 2011
    Posts
    44
    Quote Originally Posted by itCbitC View Post
    To see how variable "a" is laid out in memory you'd need to print out the contents of that location a char at a time, tho' it'd look like:
    Code:
    li'l endian:  0x0010
    big endian:   0x0100
    with address increasing from left to right, it should be 0x0001 for lill endian evident in the screenshot too. The reason i asked about visualization was that if we have any number, say int , as we read it from left to right, its endian storage reverses it if address is left to right. but, for address that increases frm right to left, it would match actual bit representation. so, i thought what visual studio is showing is not the true memory but different visualization .


    Complex data types like arrays, structs, etc. have no endianness as a whole but their elements do. So for string "AB" or "\x41\x42", the first character 'A' would be stored in memory as:
    Code:
    li'l endian:   10000010
    big endian:    01000001
    thanks for this. i will extract each bit and conform this.
    Last edited by sed_y; 09-01-2011 at 11:23 AM.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by itCbitC View Post
    IBTD, endianness applies to all types, be they char, short, integer, float or double. For the aggregate types (like arrays, structs etc.) it applies to the individual elements but not to the aggregate as a whole.
    Bit-endianness is usually only discussed in things like transmission protocols (serial, USB, I2C). CPUs rarely allow bit-level addressing, so it doesn't make sense to care about or check for bit-endianness. AFAIK, it's always assumed to be big bit-endian. I can't think of any way in C to determine bit-endianness of the architecture.

    Byte-endianness, which is regularly an issue in C programming, makes no sense whatsoever for a one-byte variable. There is only one byte, it's the first and last, and is both the least- and most-significant byte.

  9. #9
    Registered User
    Join Date
    May 2011
    Posts
    44
    I'm not sure why you're shifting the values of a byte array either - were you hoping that the result would somehow "migrate" through the array? It just doesn't work that way.
    the reason I am doing is to confirm that memory stores 0x0100 as lill endian 0x0001. when shifted 7 bits, char pointer *p gives 0x0 and *(p+1) as 0x80. if lill endian was stored as 0x0100 with LSB to right, shifting 7 bits to left
    and de-referencing the pointer would give me 0x0 and 0x0 for *(p) and *(p+1) respectively.
    people can correct me if i am wrong.

  10. #10
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by sed_y View Post
    the reason I am doing is to confirm that memory stores 0x0100 as lill endian 0x0001. when shifted 7 bits, char pointer *p gives 0x0 and *(p+1) as 0x80. if lill endian was stored as 0x0100 with LSB to right, shifting 7 bits to left
    and de-referencing the pointer would give me 0x0 and 0x0 for *(p) and *(p+1) respectively.
    people can correct me if i am wrong.
    You're wrong. Your shift will always operates on the number in byte-big-endian format, that is, 0x0001 << 7 will always be 0x0080. Whether the computer stores that as [0x00 0x80] or [0x80 0x00] is another story. You as a programmer only need to think in big-endian terms when thinking about literal values, shifting, etc. Pretty much the only time you need to check/convert is for network protocols, or when writing software that runs on multiple architectures. The "classic" check for endianness goes like this:
    Code:
    unsigned int x = 1;  // the computer may represent this as 0x01000000 or 0x00000001
    char *bytes = &x;  // bytes points to the "beginning" of the 4 bytes used for x, i.e. the lowest address
    
    if (*bytes == 1)  // if the lowest-addressed byte is one
        // system is little endian
    else
        // system is big endian

  11. #11
    Registered User gardhr's Avatar
    Join Date
    Apr 2011
    Posts
    151
    Quote Originally Posted by itCbitC View Post
    IBTD, endianness applies to all types, be they char, short, integer, float or double. For the aggregate types (like arrays, structs etc.) it applies to the individual elements but not to the aggregate as a whole.
    Hmm. For some odd reason I thought that floating point types were exempt.

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by gardhr View Post
    Hmm. For some odd reason I thought that floating point types were exempt.
    They are. The endianness of an architecture only matters on multi-byte integral types. You can have a big- or little-endian machine, either of which uses IEEE 754 for floating point. It's the IEEE 754 that specifies a sort of "endianness" for the float, i.e. bits 31: sign, 30-23: exponent, 22-0: signifcand. That isn't really an endianness though, architectually speaking, since a float is broken up into "logical" entities instead of individual bytes in a multi-byte word. You may want to address just the most or least significant bits/bytes of a word, but never of a float. Floating types are not meant to be examined on a bit-by-bit basis.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by itCbitC View Post
    lol?
    Endianness is most commonly used to explain byte ordering.
    Quote Originally Posted by wikipedia
    The most common cases refer to how bytes are ordered within a single 16-, 32-, or 64-bit word, and endianness is then the same as byte order.[1] The usual contrast is whether the most significant or least significant byte is ordered first — i.e. at the lowest byte address — within the larger data item. A big-endian machine stores the most significant byte first, and a little-endian machine stores the least significant byte first. In these standard forms, the bytes remain ordered by significance.
    Why? Because no one cares about what end of a bit is the highest bit.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    May 2011
    Posts
    44
    Quote Originally Posted by anduril462 View Post
    You're wrong. Your shift will always operates on the number in byte-big-endian format, that is, 0x0001 << 7 will always be 0x0080. Whether the computer stores that as [0x00 0x80] or [0x80 0x00] is another story. You as a programmer only need to think in big-endian terms when thinking about literal values, shifting, etc. Pretty much the only time you need to check/convert is for network protocols, or when writing software that runs on multiple architectures.
    you are right. I knew this and explained it in stupid manner. of course, 0x0100 when shifted 7 bits wld give 0x8000 which if stored as lill endian cld be 0x0080(left to right add) or 0x8000(right to left add). so, my *p confirms left to right addressing (after i determine endianness by the classic code you mentioned, because unless i know endianness, 0x0080 cld also result from right to left adressing and big endian format).

    thanks

  15. #15
    Registered User
    Join Date
    May 2011
    Posts
    44
    Quote Originally Posted by itCbitC View Post
    To see how variable "a" is laid out in memory you'd need to print out the contents of that location a char at a time, tho' it'd look like:
    Code:
    li'l endian:  0x0010
    big endian:   0x0100
    Yep!

    Complex data types like arrays, structs, etc. have no endianness as a whole but their elements do. So for string "AB" or "\x41\x42", the first character 'A' would be stored in memory as:
    Code:
    li'l endian:   10000010
    big endian:    01000001
    hi, I did verify this bitwise. however, i we compute *p where p points to A, value still comes as 0x41. so, is it that internally storage is 10000010 or 0x82 but compiler automatically understands and shows us the output as 0x41?
    also, this is not the case with integer or other arrays. was there a reason why strings were made like this?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. endian
    By kiros88 in forum C Programming
    Replies: 18
    Last Post: 06-19-2010, 04:08 PM
  2. big endian-small endian problem
    By kapil1089thekin in forum C Programming
    Replies: 3
    Last Post: 05-15-2008, 06:47 PM
  3. Big Endian & Little Endian
    By swaugh in forum C Programming
    Replies: 18
    Last Post: 06-06-2007, 11:25 PM
  4. Big Endian Little Endian Complex- Converting Characters
    By bd02eagle in forum C Programming
    Replies: 3
    Last Post: 07-11-2006, 01:01 AM
  5. Big endian/Little endian conversion
    By bonkey in forum Windows Programming
    Replies: 5
    Last Post: 09-25-2002, 02:29 PM

Tags for this Thread