Reputation: 437
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
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
Reputation: 133919
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