How is each byte in an integer stored in CPU / memory?

7

i have tried this

char c[4];
int i=89;
memcpy(&c[0],&i,4);
cout<<(int)c[0]<<endl;
cout<<(int)c[1]<<endl;
cout<<(int)c[2]<<endl;
cout<<(int)c[3]<<endl;

the output is like:
89
0
0
0

which pretty trains my stomache cuz i thought the number would be saved in memory like 0x00000059 so how come c[0] is 89 ? i thought it is supposed to be in c[3]...

c++
memcpy
endianness
asked on Stack Overflow Dec 3, 2009 by Pyjong • edited Dec 8, 2009 by Gregory Pakosz

6 Answers

33

Because the processor you are running on is little-endian. The byte order, of a multi-byte fundamental type, is swapped. On a big-endian machine it would be as you expect.

answered on Stack Overflow Dec 3, 2009 by Goz • edited Jul 3, 2013 by 0x499602D2
12

This is because you're running the program on a little endian cpu. See also endianness here and there.

answered on Stack Overflow Dec 3, 2009 by Gregory Pakosz • edited Dec 15, 2009 by Gregory Pakosz
9

Endian-ness is obviously the answer as Goz has pointed out.

But for those who are unclear of what that means, it's also important to understand that the order of bytes displayed in the example is the same as the order in the original int. Memcpy doesn't change the byte order, regardless of the edian type of the platform.

answered on Stack Overflow Dec 3, 2009 by Alan
6

Because byte order is an arbitrary design decision. Once in a register, there is no byte order1.

Byte order arises when we address smaller units like bytes. It's an essentially arbitrary decision the CPU designer gets to make: big-endian or little-endian.

It's useful to simplify the situation and realize that it is mainly the connection to peripherals that is byte ordered. Yes, it can be discovered via byte addressing as you have proved, but in general scalar values are loaded and stored as units, into registers, and in this case byte order doesn't change anything. The most significant bits are on "the left", at least, the way we usually write numbers. And that's why the << and >> operators always produce the exact same results on big-endian vs little-endian machines when used according to the language standards.

But in order to read and write data streams to peripheral devices, you are forced to choose a byte order. This is because peripherals are fundamentally byte stream devices. Does the lowest address have the most significant bits or the least? It's done both ways and the camps used to be rather evenly divided.

Because memory itself is byte addressed, it's certainly possible to derive different behavior without a peripheral, but this typically doesn't happen without a deliberate peek inside like you did.

Imagine a CPU that has no bytes, only 32-bit words, addressed as 0, 1, 2. The C compiler makes char, int, and long all 32-bit objects. (This is allowed by Cx9.) Wow, no byte order issues! It's both! But .. what happens when we hook up our first peripheral??


1.Well, x86 has registers that alias smaller registers, but that's another story.

answered on Stack Overflow Dec 4, 2009 by DigitalRoss • edited Dec 4, 2009 by DigitalRoss
2

Different machines can have different byte ordering, but take a look at this code and think about what happens, depending on how the bytes are laied out:

long x = 89;
short *p = (short*)&x;
short y = *p;
answered on Stack Overflow Dec 3, 2009 by Dan Byström
1

If you want your application to be portable or developed within a team, you probably don't want to follow this logic as it would cause hard to catch bugs and prolong development.

answered on Stack Overflow Dec 3, 2009 by Daniel

User contributions licensed under CC BY-SA 3.0