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

时间:2017-04-09 11:43:42

标签: c arrays assembly x86

我正在实现一个简单的汇编函数,该函数通过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 <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;
}

1 个答案:

答案 0 :(得分:1)

1添加到ESI

subl $-1,%esi

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

因为

jg startloop

您未达到decl %esi,因此永远不会遇到中断条件jl endloop

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

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