does 8-bit processor have to face endianness problem?
Asked Answered
C

7

5

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.

Cammi answered 19/3, 2010 at 12:54 Comment(3)
There's only one situation where you needn't bother with big/little endian, and that's where you have no multibyte integers. As long as communication channels are standardized to using 8bit units, you're only safe when using 8 bits. If your communication channel uses any other size, you'd have to worry about endian even with 8 bit units (e.g. nibbles, which nibble is the high and which is the low one?) This has nothing to do with the type of processor.Benedetto
Heck, even if you have no multibyte integers, the channel designer had to specify lsb-first or msb-first on the wire, and the people working building the device had to respect that...Deloresdeloria
Yes, that's exactly my case. When I transfer multy-byte data on the wire, I have to both know the protocol and the memory layout...Cammi
M
8

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

Mickens answered 19/3, 2010 at 13:10 Comment(2)
Also, the Keil C51 compiler stores integers in big endian format.Katelyn
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.Besetting
E
5

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&thread=14207 suggests that the 8051 mixes different endian-ness in different places.

Esmeralda answered 19/3, 2010 at 13:18 Comment(1)
Thanks! I will see into caf's, SF's and your answer together to came up with an idea. Thanks for your link ;)Cammi
V
3

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

Vain answered 19/3, 2010 at 12:59 Comment(2)
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.Deafmute
Yes, but as Douglas pointed out, as soon as you send the data anywhere you have to deal with the endianness.Peafowl
S
3

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

Summerlin answered 19/3, 2010 at 13:29 Comment(0)
D
2

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.

Draff answered 19/3, 2010 at 12:59 Comment(0)
C
1
unsigned long int x = 1;
unsigned char *px = (unsigned char *) &x;

*px == 0 ? "big endian" : "little endian"

If x is assigned the value 1 then the value 1 will be in the least significant byte. If we then cast x to be a pointer to bytes, the pointer will point to the lowest memory location of x. If that memory location is 0 it is big endian, otherwise it is little endian.

Christianity answered 22/4, 2010 at 16:25 Comment(1)
It is just a way to test, not an answer.Cammi
C
0
#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.

Correll answered 19/3, 2010 at 12:59 Comment(1)
Or use memcpy, which makes slightly weaker assumptions about the implementation: int asint; char asbytes[sizeof(int)]; <set the bytes>; memcpy(&i, asbytes, sizeof(int));.Antipus

© 2022 - 2024 — McMap. All rights reserved.