Макет памяти массива - PullRequest
       4

Макет памяти массива

1 голос
/ 06 апреля 2011

После некоторой игры с разными типами массивов я определил, что для каждого элемента требуется 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 содержит второй элемент массива.

Мой вопрос касается содержимого 0x080490a5, 0x080490a6, 0x080490a7.Каково значение этих мест памяти?Я пропускаю некоторые детали о том, как работают массивы?

1 Ответ

0 голосов
/ 09 апреля 2011

Размер каждого элемента массива не имеет ничего общего с количеством элементов в массиве.Он определяется только типом данных, которые хранятся в массиве.Если у вас есть 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 - адрес второго элемента массива
  • 0x080490a5, 0x080490a6 и 0x080490a7 - все адреса не выровнены (т.е. они не кратны размеру слова), каждый из которых указывает на 4 байта.Из этих 4 байтов некоторые принадлежат первому, а другие - второму элементу.

Из-за того, что процессоры x86 имеют little-endian , где наименьший значащий байт (LSB) на первом месте, расположение в физической памяти этих двух элементов будет:

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

Увеличивая адрес на один байт, ваш компьютер видит:

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

Т.е. значение, хранящееся в 0x080490a5, имеет:

  • в качестве трех младших байтов, трех старших байтов первого элемента массива

  • в качестве самого старшего байта первого байта (т. Е. Самого младшего байта) второго элемента массива

И так как x86 имеет младший порядок байтов, и GDB re-упорядочивает байты, которые он показывает, так что MSB отображается первым, вы получаете:

0x80490a5: 00010100 00000000 00000000 00000000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...