【发布时间】:2015-03-21 18:05:48
【问题描述】:
我们刚刚开始讨论关于装配的话题,而我在这个问题上被困的时间最长。鉴于以下情况,我必须将程序集转换为 C 代码:
C 代码:
int foo(int *a, int n, int val) {
int i;
for (i = _________; ____________________________ ; i =___________) {
;
}
return i;
}
组装:
// what I've gathered so far
foo()
:
foo:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ecx // ecx: a
movl 16(%ebp),%edx // edx: val
movl 12(%ebp),%eax // eax: n
decl %eax // n = n--
js .L3 // if n < 0 goto done
.L7: // loop
cmpl %edx,(%ecx,%eax,4) // I don't understand how you would compute the
// address for (%ecx,%eax,4) I know it would be %ecx + %eax*4 = %ecx + eax << 2
jne .L3 // if (%ecx, %eax, 4) != val goto done (?)
decl %eax // n = n--
jns .L7 // if (n >= 0) jump to loop
.L3: // done
movl %ebp,%esp
popl %ebp
ret
我不知道如何弄清楚 i 被初始化为什么以及循环的主体是什么。我假设 i = n 因为 n 作为更新。似乎有两个条件,一个是 n > 0,另一个是 cmpl 线。如果我对代码的理解不正确,请纠正我,非常感谢任何有关此问题的线索。
【问题讨论】:
-
它在一个数组中寻找一个值,但我不会为你写一个实际上相当简单的循环。小心结束条件!。
-
...循环的主体是什么:在 C 中,循环可以没有主体。根据您的 C 模式中显示的形式,情况似乎如此。所有有趣的工作都是在初始条件(第一个
__)、测试条件(第二个__)和“增量”语句(第三个__)中完成的。 -
编译器设法为函数中的所有局部变量使用寄存器。这是一个简单的循环,你几乎做对了。
for语句中的第一个和最后一个表达式非常简单,条件表达式测试 2 个条件。还要记住a是一个指向ints 数组的指针。 -
另一个线索:这个循环的编写方式很麻烦。您可以简化它以保持相同的语义,同时删除更新(第三个)表达式并使编译的代码更短。
-
@chqrlie 我的猜测是发布的 C 代码是作业所需的模板。