J Mei - 2 months ago 9
C Question

# Finding the dimensions of an array through assembly

I have an assignment to reverse engineer the assembly to find the values of R, S, and T in the following code. Assume that R, S, and T are constants declared with

`#define`
.

``````long int A[R][S][T];
int store_ele(int h, int i, int j, long int *dest)
{
A[h][i][j] = *dest;
return sizeof(A);
}
``````

When compiling this program, GCC generates the following assembly code (with -O2):

`````` store_ele:
movslq    %esi, %rsi          //%rsi = h
movslq    %edi, %rdi          //%rdi = i
movq    (%rcx), %rax          //moves the value from %rcx to %rax
leaq    (%rdi,%rdi,4), %rdi   //%rdi = 4 * i + i
leaq    (%rsi,%rsi,4), %rcx   //%rcx = 4 * h + h
movslq    %edx, %rdx          //%rdx = j
leaq    (%rcx,%rdi,4), %rcx   //%rcx = 4 * %rdi + %rcx  = 4 * (4 * i + i) + (4 * h + h)
movq    %rax, A(,%rdx,8)      //moves some value
movl    \$1120, %eax           //%eax = 1120
ret                           //returns %eax
``````

I want to ask if what I am understanding about the assembly is right and any tips or assistance is appreciated!

Edit: I don't know what it is called but our prof. defines
`movq: source, destination`
and other similar assembly instructions where the first argument is source and second is destination

Edit 2: Biggest issue is how do I find the values of the three constants just based on the assembly. I think

``````movq   %rax, A(,%rdx,8) //moves some value
movl   \$1120, %eax      //%eax = 1120
ret                     //returns %eax
``````

Is going to play the main role in finding out what it does but I don't know what to do with it.

That's x86-64 AT&T syntax (mnemonic source, dest), with the x86-64 System V ABI (first arg in rdi, see this approximate summary of that calling convention, or find links to better ABI docs (including the official standards) in the tag wiki).

What you're calling "functions" are assembly instructions. Each one assembles to a single machine instruction.

Since you know the declaration is `long int A[R][S][T]`:
`A[h][i][j]` is equivalent to `*(A[h][i] + j)`, where `A[h][i]` is an array type (with size `[T]`). Applying this recursively, `A[h][i][j]` is equivalent to `*(base_pointer + S*T*h + T*i + j)` (where base_pointer is just a long*, for the purposes of C pointer math which implicitly scales by sizeof(long) in this case).
Then to find R, look at the function return value, which is `R*S*T * sizeof(long)`.
`sizeof(long)` in the x86-64 System V ABI is 8 bytes. The offset into the array is scaled by 8 bytes, too, of course, so don't forget to factor that out when getting your S and T values.