#C64 machine code, 29 bytes
sub routine; assumes input in A and X registers; returns result in $FB/$FC
machine code:
85 02 a9 00 85 FB 85 FC
E8 CA E4 02 30 0E 8A F0
F8 4A 90 FB E6 FB 90 F7
E6 FC D0 F3 60
assembler source code:
STA $02 store lower bound in $02
LDA #0 init result to 0
STA $FB
STA $FC
INX increment upper bound
LOOP1: DEX decrement upper bound
CPX $02 compare to lower bound
BMI :ENDE if smaller, return
TXA copy X to A
LOOP2: BEQ :LOOP1 if 0, next outer loop
LSR shift right
BCC :LOOP2 if carry is clear, next inner loop
INC $FB else increment result
BCC :LOOP2
INC $FC
BNE :LOOP2 next inner loop
ENDE: RTS
notes
- The maximum possible number of set bits is 1024; so incrementing the MSB (
INC $FC
) always has a non-zero result; henceBNE :LOOP
always branches. BEQ
following thatBNE
never branches, even not if the accumulator is zero; but that doesn´t matter:LSR
will clear the carry and set the zero flag,BCC
will hop toLOOP2
and theBEQ
toLOOP1
.- I´m not completely sure (it´s been so long I actually coded on the C64), but it may fail if the range is larger than 127:
CPX $02
is actually a substraction; if the result is >127, the negative flag may be set, soBMI
would end the routine. - I hope I got the branching parameters correct - I assembled the machine code manually.