x86-64 Machine Code, 26 bytes
31 C9 8D 71 01 89 F8 FF C1 99 F7 F9 85 D2 75 03 0F AF F1 39 F9 7C EE 89 F0 C3
The above code defines a function that takes a single parameter (the input value, a positive integer) in EDI
(following the System V AMD64 calling convention used on Gnu/Unix), and returns a single result (the product of divisors) in EAX
.
Internally, it computes the product of divisors using an (extremely inefficient) iterative algorithm, similar to pizzapants184's C submission. Basically, it uses a counter to loop through all of the values between 1 and the input value, checking to see if the current counter value is a divisor of the input. If so, it multiplies that into the running total product.
Ungolfed assembly language mnemonics:
; Parameter is passed in EDI (a positive integer)
ComputeProductOfDivisors:
xor ecx, ecx ; ECX <= 0 (our counter)
lea esi, [rcx + 1] ; ESI <= 1 (our running total)
.CheckCounter:
mov eax, edi ; put input value (parameter) in EAX
inc ecx ; increment counter
cdq ; sign-extend EAX to EDX:EAX
idiv ecx ; divide EDX:EAX by ECX
test edx, edx ; check the remainder to see if divided evenly
jnz .SkipThisOne ; if remainder!=0, skip the next instruction
imul esi, ecx ; if remainder==0, multiply running total by counter
.SkipThisOne:
cmp ecx, edi ; are we done yet? compare counter to input value
jl .CheckCounter ; if counter hasn't yet reached input value, keep looping
mov eax, esi ; put our running total in EAX so it gets returned
ret
The fact that the IDIV
instruction uses hard-coded operands for the dividend cramps my style a bit, but I think this is pretty good for a language that has no built-ins but basic arithmetic and conditional branches!