Search code examples
c32-bitdisassembly

Disassembling IA32 32 bit AT&T assembly code of a function in C


[Edited] Could someone explain to me how we get the values of M and N in this problem, going through each line of the corresponding assembly code?

I always get stumped at the movl array2 part.

M and N are constants defined using #define

#define M <some value>
#define N <some value>

int array1[M][N]; 
int array2[N][M];
int copy(int i, int j)
{
array1[i][j] = array2[j][i];
}

If the above code generates the following assembly code: How do we deduce the values of the constants M and N?

  copy:
    pushl %ebp
    movl %esp, %ebp 
    pushl %ebx
    movl 8(%ebp), %ecx 
    movl 12(%ebp), %ebx
    leal (%ecx, %ecx, 8), %edx
    sall $2, %edx 
    movl %ebx, %eax 
    sall $4, %eax 
    subl %ebx, %eax 
    sall $2, %eax
    movl array2(%eax, %ecx, 4), %eax
    movl %eax, array1(%edx, %ebx, 4)
    popl %ebx
    movl %ebp,%esp 
    popl %ebp
    ret

Solution

  • Alright guys, after much research I was able to find a solution. Correct me if I am wrong.

    So going through the following assembly step by step: (Added line numbers for ease)

    M and N are constants defined using #define

    int array1[M][N]; 
    int array2[N][M];
    int copy(int i, int j)
    {
    array1[i][j] = array2[j][i];
    }
    
    copy:
       1  pushl %ebp 
       2  movl %esp, %ebp 
       3  pushl %ebx
       4  movl 8(%ebp), %ecx 
       5  movl 12(%ebp), %ebx
       6  leal (%ecx, %ecx, 8), %edx
       7  sall $2, %edx 
       8  movl %ebx, %eax 
       9  sall $4, %eax 
      10  subl %ebx, %eax 
      11  sall $2, %eax
      12  movl array2(%eax, %ecx, 4), %eax
      13  movl %eax, array1(%edx, %ebx, 4)
      14  popl %ebx
      15  movl %ebp,%esp 
      16  popl %ebp
          ret
    
    1. Push %ebp into stack

    2. %ebp points to %esp

    3. Push %ebx into stack

    4. %ecx equals int i (index for array access)

    5. %ebx equals int j (index for array access)

    6. %edx equals 8 * %ecx + %ecx or 9i

    7. %edx equals 36i after a left binary shift of 2

    8. %eax equals %ebx or j

    9. %eax equals 16j after a left binary shift of 4

    10. %eax equals %eax - %ebx = 16j - j = 15j

    11. %eax equals 60j after a left binary shift of 2

    12. %eax equals array2 element with index [4%ecx + %ebx] or [4i + 60j]

    13. Element with index [ 4%ebx + %edx ] or [ 4j + 36i ] of array1 equals %eax or [4i + 60j]

    A swap of the two array elements done in 12 and 13 using %eax as intermediary register.

    1. %ebx popped

    2. %esp's old value restored

    3. %ebp popped

    Now we assume array1[i][j]'s element access to be equal to 4Ni + 4j

    And array2[j][i]'s element access to be equal to 4Mj + 4i.

    ( The 4 in each index term as int is of 4 bytes and i, j are individual offsets from starting array location ) This is true because C stores arrays in a row major form.

    So equating we get, M = 15 and N = 9.