2017-10-16 93 views
0

[编辑] 有人可以向我解释在这个问题中,我们如何得到M和N的值,遍历相应汇编代码的每一行?反编译IA32 32位AT&T汇编代码中的一个函数C

我总是被困在movl array2部分。我们如何推导出常数M和N的值:

M和N常量使用#

#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]; 
} 

如果上述代码生成以下汇编代码中定义?

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 
+2

你真的希望我们输入所有的?不要发布代码图片!请解决你的问题。 – ikegami

+0

为什么代码为图像? –

+0

当你说“我们得到M和N的值”时,你是什么意思?你的意思是'我'和'j'? – ikegami

回答

0

好吧,经过很多研究,我可以找到解决方案。纠正我,如果我错了。

通过以下步骤组装所以要通过步骤:(由行号为便于)

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 $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. %ebp入堆栈

  2. 定义的常量
  3. %ebp%esp

  4. %ebx入堆栈

  5. %ecx等于int i(指数为数组访问)

  6. %ebx等于int j(指数为数组访问)

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

  8. %edx2

  9. %eax左二进制移位后等于36i等于%EBX或j

  10. %eax4

  11. %eax左二进制移位后等于16j等于%eax - %ebx = 16j - j = 15j

  12. %eax等于60j2

  13. %eax左二进制移位后等于数组2元件与索引[4%ecx + %ebx] or [4i + 60j]

  14. 元索引[ 4%ebx + %edx ] or [ 4j + 36i ]的ARRAY1等于%eax[4i + 60j]

两个数组元素的交换在12和13中使用%eax作为 中间寄存器完成。

  • %ebx弹出

  • %esp的旧值恢复

  • %ebp弹出

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

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

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

    因此,我们得到,M = 15和N = 9。

    1

    你需要检查装配的其他部分。例如,如果定义了M和N为8两者,会发现在装配

    array1: 
        .zero 256 
    array2: 
        .zero 256 
    

    以下,因为我的机器上,int是4个字节,8次8是64和64 * 4 = 256 。样品组件可以找到here

    +0

    我认为有一种方法可以找到答案,而不必假设M和N的值,但我认为我们不需要知道程序集的其他部分。 – 24dinitrophenylhydrazine