Code machine x86-64, 26 octets
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
Le code ci-dessus définit une fonction qui prend un seul paramètre (la valeur d'entrée, un entier positif) dans EDI
(suivant la convention d'appel System V AMD64 utilisée sur Gnu / Unix), et renvoie un seul résultat (le produit des diviseurs) dans EAX
.
En interne, il calcule le produit des diviseurs en utilisant un algorithme itératif (extrêmement inefficace), similaire à la soumission C de pizzapants184 . Fondamentalement, il utilise un compteur pour parcourir toutes les valeurs comprises entre 1 et la valeur d'entrée, vérifiant si la valeur actuelle du compteur est un diviseur de l'entrée. Si c'est le cas, il multiplie cela dans le produit total en cours d'exécution.
Mnémoniques non assemblés du langage d'assemblage:
; 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
Le fait que l' IDIV
instruction utilise des opérandes codés en dur pour le dividende restreint un peu mon style, mais je pense que c'est assez bon pour un langage qui n'a pas de fonction intégrée mais des branches arithmétiques et conditionnelles de base!