我正在使用GDB检查内存地址的内容,但不知道它是否正确显示。
(gdb) p (char *)0x8182f40
$4 = 0x8182f40 "XYZ"
(gdb)
(gdb) x/40x 0x8182f40-16
0x8182f30: 0x00000000 0x00000000 0x000000a8 0x00000010
0x8182f40: 0x005a5958 0x00000000 0x00000000 0x00000029
0x8182f50: 0x00000000 0x00000000 0x00010000 0x082439d8
0x8182f60: 0x08199100 0x00000000 0x08000000 0x00002f08
0x8182f70: 0x00000002 0x000000b1 0x00000000 0x00000000
0x8182f80: 0x00000000 0x00000000 0x00000000 0x00000000
0x8182f90: 0x00000000 0x00000000 0x000000d4 0x00000002
0x8182fa0: 0x000003f1 0x00007162 0x00000002 0x08178d00
0x8182fb0: 0x00000000 0x080ef4b8 0x00000000 0x00000000
0x8182fc0: 0x00000000 0x00000000 0x0000021d 0x00000000
上面0x8182f40
的内容显示为0x005a5958
,但这看起来相反。这是对的吗?
现在每字节打印,我明白了:
(gdb) x/40bx 0x8182f40-16
0x8182f30: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8182f38: 0xa8 0x00 0x00 0x00 0x10 0x00 0x00 0x00
0x8182f40: 0x58 0x59 0x5a 0x00 0x00 0x00 0x00 0x00
0x8182f48: 0x00 0x00 0x00 0x00 0x29 0x00 0x00 0x00
0x8182f50: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
这个更有意义:0x8182f40: 0x58 0x59 0x5a
X Y Z
如何正确解释这些地址和内容?
答案 0 :(得分:3)
在内存中存储多字节值时,有两种 1 方式存储它们:
较低地址的较低字节数。这称为Little Endian或Least Presant First(LSB)。
较低地址的字节数较高。这称为Big Endian或最重要的字节优先(MSB)。
从历史上看,有些CPU是小端,有些是big endian,大端也许比较常见,但是小端仍然占优势。部分原因是最常见的ix86架构是小端。第二个最常见的体系结构ARM可以配置为传统上许多操作系统使用它作为大端(包括早期的Linux),最近每个人似乎都使用它的小端。主要原因可能是避免必须检查从ix86移植的代码是否为字节序中性。
原因是看起来“错误”只是两种惯例的冲突:
但这只是一个惯例。在计算机中,在给定int
值x
的情况下,小端可能稍微更符合逻辑,等式(char)x == *(char *)&x
成立,这在big endian中是不正确的。当然,C规范非常谨慎,不能定义此实现(使用char
它不违反严格的别名规则)。
答案 1 :(得分:1)
您可能需要设置字节顺序:http://www.delorie.com/gnu/docs/gdb/gdb_130.html
答案 2 :(得分:1)
看起来您的GDB设置为Little-Endian。有关Endianness
。