Counting the number of "on" bits in an int
The current implementation

Your implementation is correct, and takes \$O(n)\$ time, where \$n\$ is the number of bits in an int.  One thing you can improve is the initial setting of b_mask.  Currently, you use a loop, but it can be done like this:

unsigned int b_mask = 1u &lt;&lt; (sizeof(b_mask)*CHAR_BIT - 1);


Actually, there are two other strategies you can use as well:


Start b_mask at 1 and left shift it instead of right shift it.
Get rid of b_mask and shift the number instead.


For an example of #2:

int on_bits(unsigned int num)
{
    int res = 0;

    while (num != 0) {
        res += (num &amp; 0x1);
        num &gt;&gt;= 1;
    }

    return res;
}


Other implementations

There are a wide variety of ways to count bits.  You should read the wikipedia page on Hamming weight for starters.  I'll briefly mention some here:

Removing one bit per loop

There is a bit trick that removes the lowest set bit.  So instead of looping \$n\$ times (e.g. 32), you can only loop \$m\$ times, where \$m\$ is the number of bits actually set. So if there is only 1 bit set, you only have to loop once.  The code looks like this:

int on_bits(unsigned int num)
{
    int res = 0;

    while (num != 0) {
        num &amp;= num - 1;
        res++;
    }

    return res;
}


Using hardware instruction

Many CPUs have a dedicated instruction for counting bits (e.g. popcnt for X86).  Your compiler probably has a way of accessing this instruction (e.g. __builtin_popcount() for GNU.  This will be the fastest of all implementations but will be hardware and compiler dependent.

int on_bits(unsigned int num)
{
    return __builtin_popcount(num);
}


Using a lookup table

Suppose you created a lookup table with 256 entries that contained the number of bits set in each byte value 0..255.  Then your code would need to loop only 4 times instead of 32:

static const uint8_t bitsInByte[256] = { /* Prefilled in */ };
int on_bits(unsigned int num)
{
    int res = 0;

    while (num != 0) {
        res += bitsInByte[num &amp; 0xff];
        num &gt;&gt;= 8;
    }

    return res;
}


Using parallelism and bit tricks

This is described in the wikipedia article in depth.  Here I give the 32-bit version instead of the 64-bit one:

// Assumes int is 32 bits
int on_bits(unsigned int num)
{
    num -= ((num &gt;&gt; 1) &amp; 0x55555555);
    num  = (num &amp; 0x33333333) + ((num &gt;&gt; 2) &amp; 0x33333333);
    return (((num + (num &gt;&gt; 4)) &amp; 0xF0F0F0F) * 0x1010101) &gt;&gt; 24;
}


One's complement

According to later comments by the OP, being able to handle one's complement is important, and the input argument should be int instead of unsigned int.  You can still use all of the functions above, if you first prepare the input argument by stripping its sign bit, like this:

int on_bits(int num)
{
    int signBit = 1 &lt;&lt; (sizeof(int)*CHAR_BIT - 1);
    int res     = (num &amp; signBit) != 0;

    num &amp;= ~signBit;

    // Now, num has its sign bit stripped so it can be right shifted.
    // Res is 1 if the sign bit was set, or 0 if it was not.

    // Do the rest here...
}