After some playing around with different Array types I have determined that each element needs 2 bits of 'padding'. For example, if t开发者_JAVA百科he data type of the array is .int(32bits or 2^5) then there are a total of 4 memory locations( a total of 2^7 bits) dedicated to each element of the array. Another example is if the data type is .short(16 bits or 2^4) then each element of the array contains 64bits(2^6)
Here is an example.
.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
It is evident that the memory location 0x080490a4
contains the first element of the array(value 10). It is also evident that the memory location 0x080490a8
contains the second element of the array.
My question concerns the contents of 0x080490a5
, 0x080490a6
, 0x080490a7
. What is the significance of these memory locations? Am I overlooking some detail on how Arrays operate?
The size of each array element has nothing to do with the number of elements in the array. It is only determined by the type of data that is stored in the array. If you have an int[]
, each array element would be exactly as large as an int
. The size of an int
, on the other hand, is something that is dependent on the OS and hardware platform ABI and it will be 32 bits on most computer systems that you are likely to encounter.
To compute the size of each array you have to multiply the size of each element with the number of elements. So for your example of an int a[4]
:
size = sizeof(int) * 4 = 32 * 4 bits = 2 ^ 5 * 2 ^ 2 bits = 2 ^ 7 bits = 128 bits = 16 bytes
That the size of the array, not of each individual element.
Now, the x/1wt
GDB command shows the contents of the word that is stored in the provided adddress. As long as the address points to an array element, you should see its contents. But when you go from one element to the next, you need to add the number of bytes in each element instead of shifting the location by a single byte. In your case:
0x080490a4
is the address of the first array element0x080490a8
is the address of the second array element0x080490a5
,0x080490a6
and0x080490a7
are all non-aligned (i.e. they are not a multiple of the word size) addresses that point to 4 bytes each. Out of these 4 bytes, some belong to the first and some belong to the second element.
Due to the fact that x86 CPUs are little-endian, where the least significant byte (LSB) comes first, the layout in the physical memory of those two elements will be:
0x080490a4: 00001010 00000000 00000000 00000000
0x080490a8: 00010100 00000000 00000000 00000000
By increasing the address by a single byte, your computer sees:
0x080490a5: 00000000 00000000 00000000 00010100
0x080490a9: 00000000 00000000 00000000 ...
I.e. the value stored in 0x080490a5
has:
as its three least significant bytes, the three most significant bytes of the first array element
as its most significant byte the first byte (i.e. the least significant one) of the second array element
And since x86 is little-endian and GDB re-arranges the bytes it shows, so that the MSB is shown first, you get:
0x80490a5: 00010100 00000000 00000000 00000000
精彩评论