Big-Endian Testing with QEMU

Sat, 28 Mar 2026 00:00:00 GMT

In computing, the terms big endian and little endian refer to the order in which a value's bytes are stored in memory: with the most significant (big) or least significant (little) part first.

For example, the hexadecimal value 0x12345678 consists of four bytes. If we instruct a computer to store it at some memory address mem, the computer's endianness determines whether the least significant byte (0x78) or the most significant byte (0x12) gets stored at the first memory address, mem[0].

According to Wikipedia, this terminology is borrowed from the book Gulliver's Travels which tells of a conflict between those who break boiled eggs at the larger end (the Big-Endians) and the smaller end (the Little-Endians).

Some processor architectures support both modes, but most modern personal computers and smartphones are little-endian systems. (Intel x86_64 or ARM AArch64.)

When programming, it is still important to write code that runs correctly on systems with either byte order (see for example The byte order fallacy). But without access to a big-endian machine, how does one test it? QEMU provides a convenient solution. With its user mode emulation we can easily run a binary on an emulated big-endian system, and we can use GCC to cross-compile to that system.

This program (endian.c) shows the effect of the byte order:

#include <stdint.h>
#include <stdio.h>

int main(void)
{
        uint32_t x = 0x12345678;
        int i;

        for (i = 0; i < sizeof(x); i++) {
                printf("mem[%d] = 0x%02x\n", i, ((char*)&x)[i]);
        }

        return 0;
}

On my little-endian Linux machine it runs like this:

$ gcc endian.c && ./a.out
mem[0] = 0x78
mem[1] = 0x56
mem[2] = 0x34
mem[3] = 0x12

MIPS is a big-endian architecture. On a Debian system, we can install QEMU user mode emulation and GCC for MIPS like this:

$ sudo apt-get install qemu-user gcc-mips-linux-gnu

and build and run the same program:

$ mips-linux-gnu-gcc -static endian.c && qemu-mips a.out
mem[0] = 0x12
mem[1] = 0x34
mem[2] = 0x56
mem[3] = 0x78

Now we see the value stored in big-endian order!

We can get even more exotic, targeting IBM z/Architecture (s390x) which is also big-endian:

$ sudo apt-get install gcc-s390x-linux-gnu
$ s390x-linux-gnu-gcc -static endian.c && qemu-s390x a.out
mem[0] = 0x12
mem[1] = 0x34
mem[2] = 0x56
mem[3] = 0x78

Pretty neat!