tags:

views:

174

answers:

7

If I have a int32 type integer in the 8-bit processor's memory, say, 8051, how could I identify the endianess of that integer? Is it compiler specific? I think this is important when sending multybyte data through serial lines etc.

+2  A: 

The endianness is specific to the CPU architecture. Since a compiler needs to target a particular CPU, the compiler would have knowledge of the endianness as well. So if you need to send data over a serial connection, network, etc you may wish to use build-in functions to put data in network byte order - especially if your code needs to support multiple architectures.

For more information, see: http://www.gnu.org/s/libc/manual/html_node/Byte-Order.html

Justin Ethier
Unless you're using the Motorola 88000 in which case the endianess of the data in memory is defined in the instruction encoding so that big endian and little endian could be freely interchanged.
Skizz
Yes, but as Douglas pointed out, as soon as you send the data anywhere you have to deal with the endianness.
Hugh Brackett
+1  A: 

An integer does not have endianness in it. You can't determine just from looking at the bytes whether it's big or little endian. You just have to know: For example if your 8 bit processor is little endian and you're receiving a message that you know to be big endian (because, for example, the field bus system defines big endian), you have to convert values of more than 8 bits. You'll need to either hard-code that or to have some definition on the system on which bytes to swap.

Note that swapping bytes is the easy thing. You may also have to swap bits in bit fields, since the order of bits in bit fields is compiler-specific. Again, you basically have to know this at build time.

OregonGhost
A: 
#include <stdio.h>

union foo {
    int as_int;
    char as_bytes[sizeof(int)];
};

int main() {
    union foo data;
    int i;
    for (i = 0;  i < sizeof(int);  ++i) {
        data.as_bytes[i] = 1 + i;
    }
    printf ("%0x\n", data.as_int);
    return 0;
}

Interpreting the output is up to you.

Dave Hinton
Or use memcpy, which makes slightly weaker assumptions about the implementation: `int asint; char asbytes[sizeof(int)]; <set the bytes>; memcpy(`.
Steve Jessop
+4  A: 

With an 8 bit microcontroller that has no native support for wider integers, the endianness of integers stored in memory is indeed up to the compiler writer.

The SDCC compiler, which is widely used on 8051, stores integers in little-endian format (the user guide for that compiler claims that it is more efficient on that architecture, due to the presence of an instruction for incrementing a data pointer but not one for decrementing).

caf
Also, the Keil C51 compiler stores integers in big endian format.
mocj
The C51 Compiler assumes that objects accessed using **sbit** declarations are stored in little endian byte order. This is the case for **sfr16** types. However, standard C types like **int** and **long** are stored in big endian.
jschmier
+4  A: 

If the processor has any operations that act on multi-byte values, or has an multi-byte registers, it has the possibility to have an endian-ness.

http://69.41.174.64/forum/printable.phtml?id=14233&amp;thread=14207 suggests that the 8051 mixes different endian-ness in different places.

Douglas Leeder
Thanks! I will see into caf's, SF's and your answer together to came up with an idea. Thanks for your link ;)
Grissiom
+2  A: 

It's not just up to the compiler - '51 has some native 16-bit registers (DPTR, PC in standard, ADC_IN, DAC_OUT and such in variants) of given endianness which the compiler has to obey - but outside of that, the compiler is free to use any endianness it prefers or one you choose in project configuration...

SF.
A: 
Jim T
It is just a way to test, not an answer.
Grissiom