Reputation: 77
int A[R][S][T];
int A[R][S][T];
int store_ele(int i, int j, int k, int *dest) {
*dest = A[i][j][k];
return sizeof(A);
}
Gcc generates the following assembly code :
1. movl 8(%ebp), %ecx
2. movl 12(%ebp), %eax
3. leal (%eax, %eax, 8), %eax
4. movl %ecx, %edx
5. sall $6, %edx
6. sub1 %ecx, %edx
7. addl %edx, %eax
8. addl 16(%ebp), %eax
9. movl A(,%eax,4), %edx
10. movl 20(%ebp), %eax
11. movl %edx, (%eax)
12. movl $2772, %eax
Questions : https://i.sstatic.net/Ba1Z2.jpg
I don't understand line 9 in assembly code above and these questions.
Upvotes: 0
Views: 1379
Reputation: 23001
It's easiest to explain what is going on, by looking at the code one line at a time.
1. movl 8(%ebp), %ecx
This loads ecx with the parameter at ebp+8, which is i
.
2. movl 12(%ebp), %eax
This loads eax with the parameter at ebp+12, which is j
.
3. leal (%eax, %eax, 8), %eax
This sets eax to eax+eax*8, basically multiplying itself by 9. So eax is now j*9
.
4. movl %ecx, %edx
This sets edx to ecx which is i
.
5. sall $6, %edx
And this shifts it left 6 bits, multiplying it by 64, so edx is now i*64
.
6. sub1 %ecx, %edx
But now we subtract ecx (which is i
) from that value, so edx becomes i*63
.
7. addl %edx, %eax
This add edx (i*63
) to eax (j*9
), so eax is now i*63 + j*9
.
8. addl 16(%ebp), %eax
And this add the parameter at ebp+16 which is k
, so eax is now i*63 + j*9 + k
.
9. movl A(,%eax,4), %edx
This is accessing the A
array with the offset eax*4 and storing it in edx.
Since eax is i*63 + j*9 + k
, you can think of this as accessing a single dimenson int array at offset i*63 + j*9 + k
. We multiply by 4 because that's the size of an int.
Note that you can rewrite that index expression as i*7*9 + j*9 + k
. From that, I hope you can start to see how the various dimensions of the array are being accessed.
10. movl 20(%ebp), %eax
This load eax with the parameter at ebp+20, which is dest
.
11. movl %edx, (%eax)
And this stores edx, what we just got from our array, at the address in eax (dest
). It's effectively doing *dest = A[i*7*9 + j*9 + k]
if A
were a single dimension int array;
12. movl $2772, %eax
This is just returning the value 2772, the size of A
.
Since you now know the size of A
, if you look back at how i
, j
and k
have been multiplied when dereferencing the array, I'm hoping it should be fairly easy for you to figure out the values for R
, S
and T
.
UPDATE: calculating the dimensions
If the dimensions of your array are R
, S
and T
, then to access an element at i
,j
,k
, what is the formula you would use?
Think of the array as a big three dimensional block with dimensions R x S x T
. The i
index selects a two dimensional slice from that block with dimensions S x T
. The j
index selects a row from that slice of length T
. And the k
index is just the k
th item in that row.
So the one dimensional address can be represented as i*S*T + j*T + k
. Now if you look back at the array calculations in the disassembly above, do you not notice that same pattern? Can you see which values in the disassembly map to S
and T
?
As for finding R
: you know that the number of items in the array is 693 (the 2772 byte size divided by the int size of 4); and you also know that the number of items can be calculated with R*S*T
(think of the three dimensional block again). Therefore R*S*T = 693
and you know S
and T
, so finding R
is just a matter of division.
Upvotes: 1