Memory and Bytes: Endianness, Types and Addresses

A memory holds bytes, one per address, and a wider number is spread over several. Which bytes belong together, in what order and as what kind of number is decided by the instruction that reads them. Pick a read below; the bytes it takes light up with the place value each is multiplied by.

Loading interactive simulation...

Lesson

The theory — Memory and Bytes: Endianness, Types and Addresses

A byte is eight bits, a value from 0 to 255, and each address in memory holds one. A wider number takes consecutive addresses: four for a 32-bit integer. Endianness is the order of those bytes. Little-endian puts the least significant byte at the lowest address, big-endian the most significant. Read as an unsigned integer, four bytes are b₀·256⁰ + b₁·256¹ + b₂·256² + b₃·256³, where bₖ is the byte holding place k. A signed read subtracts 2³² when that sum is 2³¹ or more, and a float read decodes the same bits by IEEE 754 instead.

What each symbol means

bₖ
the byte in place k, from 0 (least significant) to 3
256ᵏ
its place value: 1, 256, 65,536 or 16,777,216
Assumes
Signed integers are two's complement and floats are IEEE 754 single precision, as on every current desktop and phone processor. Text is one byte per character, ASCII; UTF-8, which most files now use, takes up to four bytes for one character.

Read in the wrong byte order, 1 becomes 16,777,216 🖖

Press 1 read backwards. An x86 processor, and ARM as phones run it, stores 1 as a 32-bit integer with the 01 at the lowest address and three zero bytes after it: little-endian, least significant byte first. A big-endian reader takes the first byte as the most significant, so the same 01 is worth 256³, and the number is 16,777,216. The bytes did not change. Of the 4,294,967,296 possible 32-bit values, only the 65,536 whose first byte equals the fourth and second equals the third read the same either way, and −1, FF FF FF FF, is one of them. Danny Cohen named the two orders in 1980, after the war in Gulliver's Travels over which end of a boiled egg to break.

π and 1,078,530,011 are the same four bytes 🖖

Press π as an integer. Stored as a 32-bit float, π (rounded to the nearest float, 3.14159274) is the four bytes DB 0F 49 40. Read them as a signed integer and they are 1,078,530,011; switch the byte order and they are −619,755,200; as text they are two characters, I and @, and two bytes that are not printable. Nothing among the bytes says “float”. The Little Man Computer could not tell an instruction from a number. A byte memory cannot tell one kind of number from another either, and the type lives in the instruction that reads it, which is why a program that reads with the wrong type can get a wrong answer and no error.

One address off, two positive numbers read as a negative one 🖖

Press One address off. 1,000 sits at address 0 and 2,000 at address 4, both little-endian: E8 03 00 00 D0 07 00 00. A 32-bit read that starts at address 1 instead of 0 takes 03 00 00 from the first number and D0 from the second, and D0 lands in the most significant place: 3 + 208 × 256³ = 3,489,660,931. Read as a signed integer, that is −805,306,365, because the top bit of D0 is set. Neither stored number appears anywhere in the answer, and nothing in memory marked where one number ended.

Problem solved in full

  1. How big is this picture? 4 steps

    Press PNG header. These are the first 24 bytes of a PNG file. The PNG specification says every integer wider than a byte is big-endian, and that the IHDR chunk begins with the width and then the height, four bytes each. Find the width and height, and work out what a program that read them little-endian would think it had.

    Open this problem in the tool

    1. The file opens with an eight-byte signature, 89 50 4E 47 0D 0A 1A 0A. The next four bytes are the first chunk's length, big-endian: 00 00 00 0D is 13. Then its type, 49 48 44 52, which as text is IHDR. So the chunk's data starts at address 16.

    2. Width, addresses 16 to 19: 00 00 01 E0. Big-endian, the 01 is in the 256¹ place and E0, 224, in the 256⁰ place: 256 + 224 = 480. The tool's read at 16 prints the same.

    3. Height, addresses 20 to 23: 00 00 01 0E, which is 256 + 14 = 270.

    4. Little-endian, the last byte becomes the most significant. The width would be 224 × 256³ + 1 × 256² = 3,758,161,920 and the height 14 × 256³ + 256² = 234,946,560.

    Answer

    480 × 270 pixels. Read little-endian, the same bytes claim 3,758,161,920 × 234,946,560, about 8.83 × 10¹⁷ pixels, which at four bytes a pixel is 3.53 × 10¹⁸ bytes. The order is not in the file. It is in the specification, and a program has to be told it.

Learning path

How a computer runs a program

References (2)