GDB uses the target machine's native endiannes (by default1) to interpret chunks of the size you requested as integers, with addresses increasing from left to right between chunks. x86 is little-endian.
Within a chunk, 04 00
interpreted as a 16-bit little-endian integer is 0x0004
. This makes GDB dump an array of short
the way you'd expect, for example. You asked GDB for 16-bit integer chunks, so it does what you told it, showing the integer value using standard place-value notation with the leftmost digit the most significant. It's not trying to print the bytes separately because you asked for half-words.
If you want bytes in memory order, use b
. That's what it's for.
Footnote 1:
You can change GDB's endianness setting; show endian
shows the current setting. However, set endian big
causes problems, corrupting register values. e.g. when stopped at _start
:
(gdb) p /x $rsp
$1 = 0x7fffffffe6d0 # this is normal for x86-64
(gdb) set endian big
The target is assumed to be big endian
(gdb) x /16xw $rsp
0xd0e6ffffff7f0000: Cannot access memory at address 0xd0e6ffffff7f0000
(gdb) p /x $rsp
$2 = 0xd0e6ffffff7f0000 # this is obviously broken, byte-reversed
Registers don't have an endianness, and flipping them when expanding their value as an address for another command is just totally broken.
Related not exact duplicates: