简体   繁体   中英

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

You need to check other parts of the assembly. For example, if you define M and N as 8 both, you will find the following in the assembly

array1:
    .zero   256
array2:
    .zero   256

because on my machine, int is 4 bytes and 8 times 8 is 64. And 64 * 4 = 256. The sample assembly can be found here .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM