Reputation: 734
I'm implementing a simple assembly function called through a program in c, to count how many 1 there are in the odd position of an array in 32 bits. The first argument passed to the function is the pointer to the array while the second the number of elements. I do not understand what it does go to infinite loop.
// Assembly code
.globl ones_in_odds
.type ones_in_odds,@function
ones_in_odds:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ecx
movl 12(%ebp),%esi
#xorl %edi,%edi
xorl %eax,%eax
subl $-1,%esi
startloop:
cmpl $0,%esi
jl endloop
movl (%ecx,%esi,4),%edx
xorl %edi,%edi
innerloop:
cmpl $16,%edi
jg startloop
shrl %edx
shrl %edx
adcl $00,%eax
incl %edi
jmp innerloop
decl %esi
jmp startloop
endloop:
movl %ebp,%esp
popl %ebp
ret
// C Code
#include <stdio.h>
#define DIM 5
int ones_in_odds(int *,size_t);
int main(){
int array[DIM] = {1,3,4,5,6};
int one = ones_in_odds(array,DIM);
printf("Il numero di 1 nelle posizioni dispari e' %d\n",one);
return 0;
}
Upvotes: 1
Views: 94
Reputation: 14409
This adds 1 to ESI
:
subl $-1,%esi
It's like the term ESI = ESI - (-1)
. You want to transform the count of items (DIM
) to the index of the last item in array
. Thus the count has to be subtracted by 1 or added by (-1). However, you don't need this transformation at this place. Remove the line.
Because of
jg startloop
you don't reach decl %esi
and therefore the break condition jl endloop
will never been met.
Move decl %esi
to the beginning of startloop
and you solve also the transformation problem above.
As @Jester mentions, you have to follow the C calling convention since the assembly procedure is a function of the C program. The function is allowed to change EAX
, ECX
, and EDX
("caller saved") and has to return all other registers unchanged ("callee saved"). The function changes ESI
and EDI
, but should returm them unchanged. So push them at the beginning of the function and pop them at the end.
Upvotes: 1