Hamming weight ( number of 1 in a number) mixing C with assembly

后端 未结 4 1391
花落未央
花落未央 2020-12-21 11:39

I\'m trying to count how many number 1, are in the numbers of an array.

First I have a code in C lenguaje(work ok):

int popcount2(int* array, int le         


        
4条回答
  •  無奈伤痛
    2020-12-21 11:49

    assembly using 3-6 lines of code.

    This example uses a 4 instruction loop:

    popcntx proc    near
            mov     ecx,[esp+4]             ;ecx = value to popcnt
            xor     eax,eax                 ;will be popcnt
            test    ecx,ecx                 ;br if ecx == 0
            jz      popc1
    popc0:  lea     edx,[ecx-1]             ;edx = ecx-1
            inc     eax                     ;eax += 1
            and     ecx,edx                 ;ecx &= (ecx-1)
            jnz     short popc0
    popc1:  ret
    popcntx endp
    

    This example uses a 3 instruction loop, but it would be slower than the 4 instruction loop version on most processors.

    popcntx proc    near
            mov     eax,[esp+4]             ;eax = value to popcnt
            mov     ecx,32                  ;ecx = max # 1 bits
            test    eax,eax                 ;br if eax == 0
            jz      popc1
    popc0:  lea     edx,[eax-1]             ;eax &= (eax-1)
            and     eax,edx
            loopnz  popc0
    popc1:  neg     ecx
            lea     eax,[ecx+32]
            ret
    popcntx endp
    

    This is an alternative non-looping example:

    popcntx proc    near
            mov     ecx,[esp+4]             ;ecx = value to popcnt
            mov     edx,ecx                 ;edx = ecx
            shr     edx,1                   ;mov upr 2 bit field bits to lwr
            and     edx,055555555h          ; and mask them
            sub     ecx,edx                 ;ecx = 2 bit field counts
                                            ; 0->0, 1->1, 2->1, 3->1
            mov     eax,ecx
            shr     ecx,02h                 ;mov upr 2 bit field counts to lwr
            and     eax,033333333h          ;eax = lwr 2 bit field counts
            and     ecx,033333333h          ;edx = upr 2 bit field counts
            add     ecx,eax                 ;ecx = 4 bit field counts
            mov     eax,ecx
            shr     eax,04h                 ;mov upr 4 bit field counts to lwr
            add     eax,ecx                 ;eax = 8 bit field counts
            and     eax,00f0f0f0fh          ; after the and
            imul    eax,eax,01010101h       ;eax bit 24->28 = bit count
            shr     eax,018h                ;eax bit 0->4 = bit count
            ret
    popcntx endp
    

提交回复
热议问题