A simple assembly program to count the number of ones in a register I made a simple assembly program to count the number of ones in a register. Since this is basically my first ever, I would like to hear what I can improve or if there are some major flaws in this one:

#PURPOSE:  Simple program which counts the number of ones in the edx register and returns them as a status code

#INPUT:    none

#OUTPUT:   Returns the number of ones as a status code.  This can be viewed
#          by typing
#
#          echo $?
#
#          after running the program

#VARIABLES:
#          %eax holds the carry flag bits and eventually the status code
#          %ebx holds the final return value
#          %ecx stores the loop index
#      %edx stores the register whose digits are examined
#      %edi accumulates the sum of ones

.section .data

.section .text
.globl _start
_start:

movl $255, %edx         # Initialize edx to some value
movl $0, %ecx       # Initialize ecx to zero
movl $0, %edi       # Initialize edi to zero
movl $0, %eax       # Initialize eax to zero

start_loop:
    cmpl $32, %ecx      # Loop runs over all 32 bits of the register
    jge loop_exit
    inc %ecx        # Increase the index variable
    shrl $1, %edx       # Right shift edx so the LSB moves into the carry-flag
    pushf           # Get the flags register
    pop %ax         # Put the least 16 bit of the flags into ax register
    and $01, %ax        # ... but store only the LSB
    add %ax, %di        # Now add the carry bit to the result
    jmp start_loop

loop_exit:
    movl $1, %eax       # We dont need eax any more at this point so we can use it for the syscall
    movl %edi, %ebx     # Return value will be edi
    int $0x80
For some more advanced ideas, check out https://stackoverflow.com/a/109025/2189500.

But expanding on CWallach's code, how about:

mov edx, 255 ; setup edx with test value
xor eax, eax ; count

start_loop:
bt edx, 0 ; sets carry flag if bit 0 is set
adc al, 0 ; add with carry
shr edx, 1 ; drop off bit
jnz start_loop ; exit if edx is now 0



xor is a smaller instruction for setting a register to zero.
bt sets the carry flag for use in
adc adds 0 to al, but also includes the contents of the carry flag.


And once you've got your head wrapped around that, how about:

mov edx, 255 ; setup edx with test value
xor eax, eax ; count

shr edx, 1 ; move rightmost bit to carry flag
start_loop:
adc al, 0 ; add with carry
shr edx, 1 ; move rightmost bit to carry flag
jnz start_loop ; exit if edx is now 0
adc al, 0 ; count last bit


This takes advantage of the fact that when shr shifts, it moves the shifted bit into the carry flag.  And while there are more instructions overall (5 vs 6), there are fewer within the loop (4 vs 3).