阵列存储器布局

时间:2011-04-06 02:09:05

标签: arrays memory layout

在玩了不同的数组类型后,我确定每个元素需要2位'填充'。例如,如果数组的数据类型是.int(32位或2 ^ 5),则总共有4个存储器位置(总共2 ^ 7位)专用于阵列的每个元素。另一个例子是如果数据类型是.short(16位或2 ^ 4),那么数组的每个元素都包含64位(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的内容。这些内存位置有什么意义?我是否忽略了Arrays如何运作的一些细节?

1 个答案:

答案 0 :(得分:0)

每个数组元素的大小 nothing 与数组中的元素数量有关。它仅由存储在数组中的数据类型决定。如果您有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,其中最少有效字节(LSB)首先出现,因此这两个元素的物理内存布局为:

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