计算32位数组的奇数位置中有多少1个

我正在实现一个简单的汇编函数,该函数通过c中的程序调用,以计算32位数组奇数位置中有多少1个。 传递给函数的第一个参数是指向数组的指针,第二个参数是元素的数量。 我不明白它无限循环的作用。

//汇编代码

.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代码

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

这为ESI 增加了 1:

 subl $-1,%esi 

这就像术语ESI = ESI - (-1) 。 您希望将项目数( DIM )转换为array最后一项的索引 。 因此,计数必须减1或加(-1)。 但是,您不需要在此处进行此转换。 删除该行。

因为

 jg startloop 

你没有达到decl %esi ,因此永远不会遇到rest条件jl endloop

decl %esi移动到startloop的开头,您也可以解决上面的转换问题。

正如@Jester提到的那样,你必须遵循C调用约定,因为汇编过程是C程序的一个function。 该函数允许更改EAXECXEDX (“调用者已保存”)并且必须不更改所有其他寄存器(“被调用者保存”)。 该function改变了ESIEDI ,但应该保持不变。 所以在函数的开头推动它们并在结束时弹出它们。