首页 > 解决方案 > 组装说明阅读,泄漏

问题描述

所以我试图用给定的汇编代码计算下面代码中 M 和 N 的值。

int array1[M][N];
int array2[N][M];

void copyelement(int i, int j) {
    array1[i][j] = array2[j][i];
}

集会:


copyelement:
    movslq      %esi, %rsi
    movslq      %edi, %rdi
    leaq        (%rdi,%rdi,8), %rax
    addq        %rsi, %rax
    leaq        (%rsi,%rsi,2), %rdx
    leaq        (%rsi,%rdx,4), %rdx
    addq        %rdx, %rdi
    leaq        array2(%rip), %rdx
    movl        (%rdx,%rdi,4), %ecx
    leaq        array1(%rip), %rdx
    movl        %ecx, (%rdx,%rax,4)
    ret

在阅读汇编代码时,我一直通过array2(%rip),然后我不知道如何前进。

此时,根据我的计算,我应该有
%rdx = %rdi + (%rsi + %rax) + 4*((%rsi+%rax) + 2*(%rsi + %rax)).

此外,我不太确定如何从中获取数组大小。

标签: cassemblyx86-64reverse-engineering

解决方案


以下是带有注释的说明,说明它们的作用。

// Initially, edi contains i and esi contains j.

movslq %esi, %rsi          // Sign-extended 32-bit j to 64 bits.
movslq %edi, %rdi          // Sign-extended 32-bit i to 64 bits.
leaq   (%rdi,%rdi,8), %rax // rax = rdi + rdi*8 = 9*rdi = 9*i.
addq   %rsi, %rax          // rax = rax + rsi = 9*i + j.
leaq   (%rsi,%rsi,2), %rdx // rdx = rsi + rsi*2 = 3*rsi = 3*j.
leaq   (%rsi,%rdx,4), %rdx // rdx = rsi + rdx*4 = j + (3*j)*4 = 13*j.
addq   %rdx, %rdi          // rdi = rdi + rdx = i + 13*j = i + 13*j.
leaq   array2(%rip), %rdx  // rdx = array2 (address of first element).
movl   (%rdx,%rdi,4), %ecx // Load *(rdx + rdi*4) = array2[rdi] = array2[i + 13*j] into ecx.
leaq   array1(%rip), %rdx  // rdx = array1 (address of first element).
movl   %ecx, (%rdx,%rax,4) // Store ecx into (rdx + rax*4) = array1[rax] = array1[9*i + j].

因此array2[j][i],在 C 代码中是array2[i + 13*j]在汇编代码中(允许二维寻址与一维寻址)。后者应该是array2[i + M*j],所以我们可以得出结论M是 13。

同样,array1[i][j]在 C 代码中是array1[9*i + j]在汇编代码中。后者应该是array1[N*i + j],所以我们可以得出结论N是 9。


推荐阅读