【问题标题】:Array Memory Layout阵列内存布局
【发布时间】:2011-04-06 02:09:05
【问题描述】:

在尝试了一些不同的数组类型之后,我确定每个元素都需要 2 位“填充”。例如,如果数组的数据类型是 .int(32bits 或 2^5),那么总共有 4 个内存位置(总共 2^7 位)专用于数组的每个元素。另一个例子是如果数据类型是 .short(16 bits or 2^4) 那么数组的每个元素包含 64bits(2^6)

这是一个例子。

.data
IntArray:
.int 10, 20, 30, 40, 50

(gdb) info variables
0x080490a4 IntArray

(gdb) x/1wt 0x080490a4
0x80490a4 : 00000000000000000000000000001010
(gdb) x/1wt 0x080490a5
0x80490a5 : 00010100000000000000000000000000
(gdb) x/1wt 0x080490a6
0x80490a6 : 00000000000101000000000000000000
(gdb) x/1wt 0x080490a7
0x80490a7 : 00000000000000000001010000000000
(gdb) x/1wt 0x080490a8
0x80490a8 : 00000000000000000000000000010100

很明显,内存位置0x080490a4 包含数组的第一个元素(值10)。很明显,内存位置0x080490a8 包含数组的第二个元素。

我的问题涉及0x080490a50x080490a60x080490a7 的内容。这些内存位置的意义是什么?我是否忽略了有关数组如何运作的一些细节?

【问题讨论】:

  • 我有点困惑,但我只是想确保我们在同一页面上。 “2位'填充'”是什么意思?

标签: arrays memory layout


【解决方案1】:

每个数组元素的大小与数组中元素的数量无关。它仅由存储在数组中的数据类型决定。如果您有int[],则每个数组元素将与int 一样大。另一方面,int 的大小取决于操作系统和硬件平台ABI,在您可能遇到的大多数计算机系统上它将是 32 位。

要计算每个数组的大小,您必须将每个元素的大小乘以元素的数量。因此,对于您的int a[4] 示例:

size = sizeof(int) * 4 = 32 * 4 bits = 2 ^ 5 * 2 ^ 2 bits = 2 ^ 7 bits = 128 bits = 16 bytes

数组的大小,而不是每个单独元素的大小。

现在,x/1wt GDB 命令显示了存储在提供的地址中的单词 的内容。只要地址指向一个数组元素,您就应该看到它的内容。但是当您从一个元素转到下一个元素时,您需要添加每个元素中的字节数,而不是将位置移动一个字节。在你的情况下:

  • 0x080490a4是第一个数组元素的地址
  • 0x080490a8是第二个数组元素的地址
  • 0x080490a50x080490a60x080490a7 都是非对齐的(即它们不是字大小的倍数)地址,每个地址指向 4 个字节。在这 4 个字节中,一些属于第一个元素,一些属于第二个元素。

由于 x86 CPU 是 little-endian最低位在前,这两个元素在物理内存中的布局将是:

0x080490a4: 00001010 00000000 00000000 00000000
0x080490a8: 00010100 00000000 00000000 00000000

通过将地址增加一个字节,您的计算机会看到:

0x080490a5: 00000000 00000000 00000000 00010100
0x080490a9: 00000000 00000000 00000000 ...

0x080490a5 中存储的值有:

  • 作为它的三个最低有效字节,第一个数组元素的三个最高有效字节

  • 第二个数组元素的第一个字节(即最低有效字节)作为其最高有效字节

由于 x86 是 little-endian 并且 GDB 会重新排列它显示的字节,以便首先显示 MSB,因此您会得到:

0x80490a5: 00010100 00000000 00000000 00000000

【讨论】:

  • 感谢您的解释。我想我最困惑的地方是我虽然每个 32 位内存地址都指向 32 位,但现在我明白它只指向 8 位。事情就更清楚了——继续学习更多关于装配的知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 1970-01-01
  • 2012-07-28
  • 2016-09-11
  • 2012-07-18
相关资源
最近更新 更多