x86-16 machine code, 18 bytes
00000000: 89c1 9988 0e09 0150 d40a 7502 02d4 58e2 .......P..u...X.
00000010: f2c3 ..
89 C1 MOV CX, AX ; input number as loop counter
99 CWD ; zero DX as running sum
88 0E 0109 MOV BYTE PTR[AAM1+1], CL ; move loop counter to divisor
50 PUSH AX ; save input number
D4 0A AAM ; ZF if (AL % CL == 0), AH = quotient
75 02 JNZ END_LOOP ; if not ZF, continue loop
02 D4 ADD DL, AH ; otherwise add to running sum
58 POP AX ; restore input number
E2 F2 LOOP DIVLOOP ; loop until CL == 0
C3 RET ; return to caller
Callable function, input
AX, result in
Inspired by @CodyGray's excellent answer, and the comment
"It sure seems like there should be a way to make this shorter" I just had to try!
As Cody mentioned, Using
IDIV is inconvenient because it clobbers two registers including the dividend. Another is that the
ZF flag is set when the quotient is
0, however in this case we're only interested in when the remainder is
AAM, a trusty and underrated byte-sized division/modulo instruction that can be golfy. Even though it does clobber the dividend just like
DIV, it will set
ZF when the remainder is
0 which is what we want here. It's downside is that the divisor is encoded in the instruction opcode, which can be modified at runtime at a cost of 4 bytes (in real mode at least).