user3538161
user3538161

Reputation: 437

x86 assembly code confusion

We've just begun the topic on assembly and I've been stuck on this problem for the longest time. I have to convert assembly to C code given the following:

C Code:

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

Assembly:

// 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 don't know how to figure out what i is being initialized to and what the body of the loop is. I'm assuming i = n since n serves as the update. It seems as if there are two conditions one being n > 0 and the other being the cmpl line. Please correct me if my understanding of the code is incorrect, and any clues to this problem is much appreciated.

Upvotes: 1

Views: 344

Answers (2)

chqrlie
chqrlie

Reputation: 144740

An alternative using the preprocessor:

#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;
}

Of course you can only use this for fun or to tease new programmers ;-)

Upvotes: 1

I could have done some off-by 1 errors, but basically it is this:

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

The i is the %eax register; it loops from n - 1 to 0. The cmpl indexed access (%ecx,%eax,4) is addressed in bytes - this is equivalent to a[i], as size of int on ia32 is 4 bytes. The 4 bytes addressed thus is compared against val.

The %eax is implicitly returned.

Notice also, that js means < 0, and jns >= 0.


Another way to write it:

    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;

Upvotes: 1

Related Questions