x86汇编代码混乱

时间:2015-03-21 18:05:49

标签: c assembly x86 intel

我们刚开始关于装配的话题,我一直坚持这个问题的时间最长。我必须将程序集转换为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 = n,因为n用作更新。似乎有两个条件,一个是n> 0和另一个是cmpl线。如果我对代码的理解不正确,请纠正我,并且非常感谢任何有关此问题的线索。

2 个答案:

答案 0 :(得分:1)

我本可以做一些1分之一的错误,但基本上就是这样:

int foo(int *a, int n, int val) {
    int i;
    for (i = n - 1; i >= 0 && a[i] == val; i = i - 1) {
        ;
    }
    return i;
}

i%eax个寄存器;它从n - 1循环到0. cmpl索引访问(%ecx,%eax,4)以字节为单位 - 相当于a[i],因为ia32上int的大小是4字节。这样寻址的4个字节与val进行比较。

隐式返回%eax

另请注意,js表示< 0jns >= 0


另一种写作方式:

    i = n;
    i --;               //  decl %eax
    if (i < 0) {
        goto L3;        //  js .L3
    }
L7:
    if (a[i] != val)    // cmpl %edx,(%ecx,%eax,4)
        goto L3;        // jne .L3

    i --;               // decl %eax
    if (i >= 0)
        goto L7;        // jns .L7

L3:
    return i;

答案 1 :(得分:1)

使用预处理器的替代方法:

#define _________ n - 1
#define ____________________________  i >= 0 && a[i] == val
#define ___________  i + 1

int foo(int *a, int n, int val) {
    int i;
    for (i = _________; ____________________________ ; i =___________) {
        ;
    }
    return i;
}

当然,你只能用它来娱乐或取笑新程序员; - )