如何在以下程序集中计算C宏表达式的定义?

时间:2013-12-15 19:43:12

标签: c assembly x86

对于我被分配到家庭作业的问题,我遇到了很多困难。我有以下C代码和后续程序集:

int foo(int n, int A[X(n)][Y(n)], int j){
    int i;
    int result = 0;
    for (i = 0; i < X(n); i++)
        result += A[i][j];
    return result;
}

movl    8(%ebp), %eax
leal    (%eax,%eax), %edx
leal    (%edx,%eax), %ecx
movl    %edx, %ebx
leal    1(%edx), %eax
movl    $0, %edx
testl   %eax, %eax
jle     .L3
leal    0(,%ecx,4), %esi
movl    16(%ebp), %edx
movl    12(%ebp), %ecx
leal    (%ecx,%edx,4), %eax
movl    $0, %edx
movl    $1, %ecx
addl    $2, %ebx
.L4:
addl    (%eax), %edx
addl    $1, %ecx
addl    %esi, %eax  
cmpl    %ebx, %ecx
jne     .L4
.L3:
movl    %edx, %eax

我需要找出X和Y的定义。我认为n最初存储在 eax 中,然后2n存储在 edx 和3n in ECX 即可。所以我认为esi等于3n * 4.另外,因为结果最初存储为 movl $ 0,%edx ,并且以下行增加1我认为X等于 #define X(n + 1)。此外,我相信 addl%esi,%eax 将是Y.所以,因为 esi =%ecx * 4 ,Y = 4n?然而,这是我开始变得非常困惑的地方。谢谢所有。

1 个答案:

答案 0 :(得分:1)

可爱运动。

声明似乎将 A 定义为C99可变长度数组。顺便提一下,这些编译器支持非常差,在C11中是可选的。

然后可以从循环迭代中的数组步长推断内部Y(n)维度,其中 EAX 是指针而 ESI 是音调,并且似乎是定义为n * 3。对于X(n),当i = 0时,我们可以从循环进入条件推断它,并且它似乎扩展为N * 2 + 1.

#define X(n) ((n)*2+1) 
#define Y(n) ((n)*3)

带注释的程序集:

_foo:
    ;Prologue (assumed)
    push ebp
    mov ebp,esp

    ;Pre-scale N
    mov eax,[ebp+8]
    lea edx,[eax+eax]
    lea ecx,[edx+eax]   ;ECX = N*3
    mov ebx,edx         ;EBX = N*2

    ;Bail out earily if X(n) <= 0
    lea eax,[edx+1]     ;EAX = N*2+1
    mov edx,0
    test eax,eax        ;(OF=0)
    jle @@end           ;Proceed if N*2+1 > 0

    ;Prepare loop counters
    lea esi,[ecx*4]     ;ESI = N*3*sizeof int, array stride
    mov edx,[ebp+16]    ;EDX = j
    mov ecx,[ebp+12]
    lea eax,[ecx+edx*4] ;EAX = &A[0][j]

    mov edx,0           ;EDX = 0, accumulator
    mov ecx,1           ;ECX = 1, loop counter
    add ebx,2           ;EBX = N*2+2

    ;Step through the loop
@@loop:
    add edx,[eax]       ;EDX += A[i][j]
    add ecx,1           ;Increment loop counter
    add eax,esi         ;++A
    cmp ecx,ebx
    jne @@loop          ;[1..N*2+2) <=> [0..N*2+1)

@@end:
    ;Epilogue
    mov eax,edx         ;Return the sum
    pop ebp
    ret