Counting the number of ones in a doubleword can be done in several ways. The most obvious is to shift the bits in the doubleword and count the number of ones while shifting. This method works fine for a byte, because only 8 bits need to be evaluated. However when a double word need to be processed 32 cycles are necessary.

This method has one big disadvantage, a loop is required to shift the ones, which either takes a lot of cycles or takes a lot of time during a cycle. This can cause problems in PLC systems because the PLC can react to slow to a process, and can even go to stop when the cycle time is to long. In my opinion loops shall be avoided in PLC software.

A better solution is presented in Hakmem 169. This can be done with Siemens Step 7 as shown below.

FUNCTION "ONECNT" : VOID
TITLE =
//Calculate the number of ones in a double word
VERSION : 0.1
VAR_INPUT
  InputWord : DWORD ;   //Word from which the bits need to be counted
END_VAR
VAR_IN_OUT
  Result : DWORD ;      //Number of bits in the word
END_VAR
VAR_TEMP
  TInpWord : DWORD ;   
  CountTemp : DWORD ;  
  Temp1 : DWORD ;
  Temp2 : DWORD ;
  Temp3 : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =Count the ones in a doubleword.
L     0
      T     #CountTemp

      L     #InputWord
      T     #TInpWord

      L     #TInpWord
      L     DW#16#80000000
      AD   
      JZ    nmsb                        //check if the MSB (sign bit) is set.
      L     #TInpWord                   //If the sign bit is set, the method will fail
      L     DW#16#7FFFFFFF              //So the sign bit is reset and stored.
      AD                                //The stored bit will be added when the 
      T     #TInpWord                   //calculation is finished
      L     1
      T     #CountTemp

nmsb: NOP   0

      L     #TInpWord
      SRD   1
      L     DW#16#DB6DB6DB
      AD   
      T     #Temp1
      L     #TInpWord
      SRD   2
      L     DW#16#49249249
      AD   
      T     #Temp2

      L     #TInpWord
      L     #Temp1
      -D   
      L     #Temp2
      -D   
      T     #Temp3
      SRD   3
      L     #Temp3
      +D   
      L     DW#16#C71C71C7
      AD   
      L     63
      MOD  
      L     #Result
      +D   
      L     #CountTemp
      +D   
      T     #Result
END_FUNCTION