x86-64 Codice macchina, 26 byte
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
Il codice precedente definisce una funzione che accetta un singolo parametro (il valore di input, un numero intero positivo) in EDI
(seguendo la convenzione di chiamata AMD64 di System V utilizzata su Gnu / Unix) e restituisce un singolo risultato (il prodotto dei divisori) in EAX
.
Internamente, calcola il prodotto dei divisori usando un algoritmo iterativo (estremamente inefficiente), simile alla presentazione in C di pizzapants184 . Fondamentalmente, utilizza un contatore per scorrere tutti i valori compresi tra 1 e il valore di input, verificando se il valore del contatore corrente è un divisore dell'input. In tal caso, lo moltiplica nel prodotto totale corrente.
Linguaggi mnemonici non assemblati:
; 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
Il fatto che l' IDIV
istruzione utilizzi operandi hardcoded per i dividendi restringe un po 'il mio stile, ma penso che questo sia abbastanza buono per un linguaggio che non ha built-in ma rami aritmetici e condizionali di base!