x86, 41 39 octets
Implémentation plutôt simple de la formule avec entrée ecx
et sortie sur la pile.
La chose intéressante est que j'ai utilisé une fonction de cubage, mais puisque call label
c'est 5 octets , je stocke l'adresse de l'étiquette et utilise les 2 octets call reg
. De plus, comme je pousse des valeurs dans ma fonction, j'utilise un à la jmp
place de ret
. Il est très possible qu'être intelligent avec une boucle et la pile évite d'appeler entièrement.
Je n'ai pas fait d'astuces de fantaisie avec cubing, comme utiliser (k+1)^3 = k^3 + 3k^2 + 3k + 1
.
Changelog:
.section .text
.globl main
main:
mov $10, %ecx # n = 10
start:
lea (cube),%edi # save function pointer
call *%edi # output n^3
sub %ecx, %eax # n^3 - n
# edx = 0 from cube
push $6
pop %ebx # const 6
idiv %ebx # k = (n^3 - n)/6
mov %eax, %ecx # save k
call *%edi # output k^3
push %eax # output k^3
not %ecx # -k-1
call *%edi # output (-k-1)^3
inc %ecx
inc %ecx # -k+1
call *%edi # output (-k+1)^3
ret
cube: # eax = ecx^3
pop %esi
mov %ecx, %eax
imul %ecx
imul %ecx
push %eax # output cube
jmp *%esi # ret
Objdump:
00000005 <start>:
5: 8d 3d 22 00 00 00 lea 0x22,%edi
b: ff d7 call *%edi
d: 29 c8 sub %ecx,%eax
f: 6a 06 push $0x6
11: 5b pop %ebx
12: f7 fb idiv %ebx
14: 89 c1 mov %eax,%ecx
16: ff d7 call *%edi
18: 50 push %eax
19: f7 d1 not %ecx
1b: ff d7 call *%edi
1d: 41 inc %ecx
1e: 41 inc %ecx
1f: ff d7 call *%edi
21: c3 ret
00000022 <cube>:
22: 5e pop %esi
23: 89 c8 mov %ecx,%eax
25: f7 e9 imul %ecx
27: f7 e9 imul %ecx
29: 50 push %eax
2a: ff e6 jmp *%esi
Voici ma version de test qui fait tout le cubage à la fin. Une fois les valeurs placées dans la pile, la boucle de cube remplace les valeurs de la pile. Il s’agit actuellement de 42 à 40 octets, mais des améliorations devraient être apportées quelque part.
.section .text
.globl main
main:
mov $10, %ecx # n = 10
start:
push %ecx # output n
mov %ecx, %eax
imul %ecx
imul %ecx
sub %ecx, %eax # n^3 - n
# edx = 0 from imul
push $6
pop %ecx # const 6
idiv %ecx # k = (n^3 - n)/6
push %eax # output k
push %eax # output k
not %eax # -k-1
push %eax # output -k-1
inc %eax
inc %eax # -k+1
push %eax # output -k+1
dec %ecx # count = 5
add $20, %esp
cube:
mov -4(%esp),%ebx # load num from stack
mov %ebx, %eax
imul %ebx
imul %ebx # cube
push %eax # output cube
loop cube # --count; while (count)
ret
-10
une autre solution possible pourrait être-1000+4574296+4410944-4492125-4492125
par exemple. Et est-il autorisé à sortir--
ou à la+-
place de+
/-
respectivement (c'est-3 = 27+-27+-125--64--64
à- dire à la place de3 = 27-27-135+64+64
)?