Big-endian is a byte-ordering convention in which the most significant byte (MSB) of a multi-byte value is stored at the lowest memory address, with subsequent bytes stored in decreasing order of significance. It is one of two dominant endianness schemes in computing, the other being little-endian.
In practice
Endianness determines how a multi-byte integer or floating-point value is laid out in memory and transmitted over a bus or network. For a 32-bit value 0x12345678 stored at address 0x0000, a big-endian system places 0x12 at 0x0000, 0x34 at 0x0001, 0x56 at 0x0002, and 0x78 at 0x0003. This "natural" ordering matches how humans write hex values left-to-right and aligns with network byte order as defined by TCP/IP (RFC 791 and related standards), which is why big-endian is sometimes called network byte order.
In embedded systems, endianness is architecture-defined for many processors but configurable on others. Classic big-endian embedded architectures include Motorola 68k (used in older industrial and automotive systems), SPARC, and the PowerPC/MPC series popular in automotive and aerospace. Several modern architectures are bi-endian: ARM Cortex-A cores can be configured for endianness, though the exact mechanism (control register bits, boot-time strapping pins, or other means) varies by architecture version and silicon implementation; MIPS supports both modes. ARM Cortex-M cores are predominantly little-endian in practice, though the ARMv7-M architecture technically supports a big-endian configuration that very few silicon vendors expose.
Endianness becomes a practical concern whenever raw bytes cross a boundary: reading a 16- or 32-bit register from an external SPI or I2C device, parsing a serial or network protocol frame, storing structured data in flash or EEPROM, or sharing memory between a host PC (typically little-endian x86) and an embedded target. A mismatch produces silently incorrect values that are often difficult to detect without a protocol analyzer or careful byte-level logging. The EmbeddedRelated post "Endianness and Serial Communication" covers this class of bug in detail.
When writing portable embedded code, avoid type-punning through unions or pointer casts to convert between byte arrays and integers -- behavior is implementation-defined in C for many such patterns. Use explicit byte assembly with shifts and OR operations, or use compiler-provided byte-swap intrinsics (e.g., __builtin_bswap32 in GCC/Clang, or the REV instruction on ARM Cortex-M) when you need to convert between endiannesses. Standard library functions like htonl/ntohl can help in hosted or POSIX environments, but are not available on all bare-metal targets.
Discussed on EmbeddedRelated
Frequently asked
How do I know which endianness my MCU or SoC uses?
Check the architecture reference manual or datasheet. Most Cortex-M based MCUs (STM32, nRF52, LPC, SAM) are
little-endian. Classic Motorola/Freescale 68k and PowerPC/MPC parts are big-endian. Bi-endian cores like Cortex-A or MIPS require checking the boot configuration for the specific board or SoC variant.
Why does endianness matter when reading a sensor over SPI or I2C?
Many sensor datasheets specify the
byte order of multi-byte output
registers. If the sensor sends the MSB first (big-endian) but your code simply reads two bytes and places the first byte in the low half of a 16-bit variable (as a
little-endian processor would interpret it), the resulting value will be incorrect by a factor of 256 or more. Always consult the sensor datasheet and assemble bytes explicitly using shifts and OR operations.
What is 'network byte order' and is it always big-endian?
Yes. Network
byte order is defined as big-endian for
TCP/IP protocols. Functions like htonl() (host-to-network long) and ntohl() convert between host endianness and network byte order. On a big-endian host these functions are no-ops; on a
little-endian host they perform a byte swap.
Is it safe to use a union to reinterpret bytes as an integer for endianness conversion in C?
Type-punning through unions is widely used in embedded C and is explicitly permitted by
GCC documentation. In
C99/C11, it is commonly treated as implementation-defined or conditionally supported rather than strictly portable -- compilers such as GCC and Clang document that they support it, but the C standard does not formally guarantee the behavior in all contexts. It is undefined behavior in C++. The safest portable approach is to assemble or disassemble multi-byte values using explicit shift-and-OR operations or memcpy, which all conforming compilers handle correctly.
Can big-endian and little-endian devices share a memory-mapped interface without conversion?
Generally no. If a
little-endian CPU writes a 32-bit value into shared
SRAM and a big-endian CPU reads it as a 32-bit word, the bytes will be interpreted in reverse order, producing a wrong value. Either the software on one side must byte-swap, or the interconnect hardware must include a byte-swap engine, which some SoC bus bridges provide.
Differentiators vs similar concepts
Big-endian stores the most significant byte at the lowest address;
little-endian (used by x86, ARM Cortex-M in typical deployments,
RISC-V, and most modern MCUs) stores the least significant byte at the lowest address. Middle-endian (PDP-endian) orderings exist historically but are essentially absent from modern embedded targets. Bi-endian architectures such as ARM Cortex-A and MIPS support both modes, selectable at boot or, on some cores, per memory transaction. The distinction from bit-endianness (the order of bits within a byte on serial interfaces like
SPI) is separate and should not be conflated with byte
endianness.