反汇编 C 函数的 IA32 32 位 AT&T 汇编代码

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

[已编辑] 有人可以向我解释一下我们如何在这个问题中通过相应的汇编代码的每一行来获取 M 和 N 的值吗?

我总是对 movl array2 部分感到困惑。

M和N是使用#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];
}

如果上述代码生成如下汇编代码:我们如何推导出常量M和N的值?

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

您需要检查程序集的其他部分。比如你把M和N都定义为8,你会在程序集中发现如下

array1:
    .zero   256
array2:
    .zero   256

因为在我的机器上,int 是 4 个字节,8 乘以 8 是 64。而 64 * 4 = 256。示例程序集可以找到 here

好的伙计们,经过大量研究,我找到了解决方案。如果我错了请纠正我。

所以逐步完成以下汇编:(为方便添加行号)

M 和 N 是使用#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 , %edx 
   8  movl %ebx, %eax 
   9  sall , %eax 
  10  subl %ebx, %eax 
  11  sall , %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. %ebp压入堆栈

  2. %ebp指向%esp

  3. %ebx压入堆栈

  4. %ecx等于int i(数组访问索引)

  5. %ebx等于int j(数组访问索引)

  6. %edx 等于 8 * %ecx + %ecx9i

  7. %edx 左二进制移位 2

  8. 后等于 36i
  9. %eax 等于 %ebx 或 j

  10. %eax 左二进制移位 4

  11. 后等于 16j
  12. %eax 等于 %eax - %ebx = 16j - j = 15j

  13. %eax 左二进制移位 2

  14. 后等于 60j
  15. %eax 等于索引为 [4%ecx + %ebx] or [4i + 60j]

  16. 的 array2 元素
  17. array1 的索引为 [ 4%ebx + %edx ] or [ 4j + 36i ] 的元素等于 %eax[4i + 60j]

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

  1. %ebx 弹出

  2. %esp的旧值已恢复

  3. %ebp 弹出

现在我们假设 array1[i][j] 的元素访问等于 4Ni + 4j

array2[j][i]的元素访问等于4Mj + 4i

(每个索引项中的 4 作为 int 是 4 个字节,i、j 是从起始数组位置开始的各个偏移量) 这是真的,因为 C 以行主要形式存储数组。

所以我们得到 M = 15 和 N = 9。