对于我被分配到家庭作业的问题,我遇到了很多困难。我有以下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?然而,这是我开始变得非常困惑的地方。谢谢所有。
答案 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