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

C GDB是否正确解释内存地址?,c,gdb,C,Gdb,我正在使用GDB检查内存地址的内容,但不知道它是否正确显示 (gdb) p (char *)0x8182f40 $4 = 0x8182f40 "XYZ" (gdb) (gdb) x/40x 0x8182f40-16 0x8182f30: 0x00000000 0x00000000 0x000000a8 0x00000010 0x8182f40: 0x005a5958 0x00000000 0x00000000

我正在使用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


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

您可能需要设置endianness:

看起来您的GDB被设置为Little Endian。请参阅,以了解有关这方面的更多详细信息

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

  • 较低地址上的较低字节。这称为小尾数或最低有效字节优先(LSB)

  • 较低地址上的较高字节。这称为Big-Endian或最高有效字节优先(MSB)

历史上,有些CPU是小端,有些是大端,而大端可能更常见,但小端占了上风。部分原因是最常见的ix86架构是little endian。第二种最常见的体系结构ARM可以配置为任意一种,虽然传统上许多操作系统都将其作为big-endian(包括早期的Linux)使用,但最近似乎每个人都在使用little-endian。主要原因可能是为了避免检查从ix86移植的代码是否与endian无关

原因是“错误”只是两个惯例的冲突:

  • 数字从左到右写入,最重要的数字在前
  • 内存内容按地址递增的顺序从左向右写入
  • 但这仅仅是一个惯例。在计算机中,在给定
    int
    value
    x
    时,小尾端的逻辑性可能稍高一些,等式
    (char)x==*(char*)&x
    在大尾端中不成立。当然,C规范非常小心地定义了这个实现(使用
    char
    它不会违反严格的别名规则)


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

    GDB最有可能被设置为小端,因为平台几乎肯定是小端。大端元平台几乎灭绝。端元性几乎肯定是建筑的正确设置。所以在这种情况下,当打印为单词时,表示最高地址
    0x8182f43=>0x00'
    先写入,然后是递减地址
    0x8182f42=>0x5a'
    0x8182f41=>0x59'
    0x8182f40=>0x58'