GDB是否正确解释了内存地址?

我正在使用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
XYZ
0x8182f40: 0x58 0x59 0x5a
XYZ

如何正确解释这些地址和内容?

那是小端 。

在内存中存储多字节值时,有两种方法可以存储它们:

  • 较低地址的较低字节。 这称为Little Endian或Least Significant Byte First(LSB)。

  • 较低地址的字节数较高。 这称为Big Endian或最重要的字节优先(MSB)。

从历史上看,有些CPU是小端的,有些是big endian,大端可能更常见,但是小端是盛行的。 部分原因是最常见的ix86架构是小端。 第二个最常见的体系结构ARM可以配置为传统上许多操作系统都使用它作为大端(包括早期的Linux),最近每个人似乎都使用它的小端。 主要原因可能是避免必须检查从ix86移植的代码是否是字节序中立的。

原因是看起来“错误”只是两个公约的冲突:

  1. 数字从左到右书写,最重要的数字首先
  2. 存储器的内容按地址递增的顺序从左向右写入。

但这只是一个惯例。 在计算机中,在给定intx ,little endian可能稍微更符合逻辑,等式(char)x == *(char *)&x成立,在big endian中不是这样。 当然,C规范足够小心,可以定义这个实现(使用char它不违反严格的别名规则)。

1 PDP-11采用第三种方式,一种称为中间端的特殊憎恶,其中16位值为小端,但32位值由大端的两个16位单元组成。

您可能需要设置字节顺序: http : //www.delorie.com/gnu/docs/gdb/gdb_130.html

看起来你的GDB被设置为Little-Endian。 有关Endianness更多详细信息,请参阅http://en.wikipedia.org/wiki/Endianness 。