Je pense que vous regardez cela dans le mauvais sens. Au lieu de retirer les vieilles variables de la pile et de pousser les nouvelles, il suffit de réaffecter celles qui sont déjà là (attention). C'est à peu près la même optimisation qui se produirait si vous réécriviez le code comme étant l'algorithme itératif équivalent.
Pour ce code:
int fact(int x, int total=1) {
if (x == 1)
return total;
return fact(x-1, total*x);
}
serait
fact:
jmpne x, 1, fact_cont # if x!=1 jump to multiply
retrn total # return total
fact_cont: # update variables for "recursion
mul total,x,total # total=total*x
sub x,1,x # x=x-1
jmp fact #"recurse"
Il n'y a pas besoin de pop ou de pousser quoi que ce soit sur la pile, réassigner simplement. De toute évidence, cela peut être encore optimisé, en mettant la condition de sortie en second lieu, ce qui nous permet de sauter un saut, ce qui entraîne moins d'opérations.
fact_cont: # update variables for "recursion
mul total,x,total # total=total*x
sub x,1,x # x=x-1
fact:
jmpne x, 1, fact_cont # if x!=1 jump to multiply
retrn total # return total
regardant de nouveau, cette « assemblée » reflète mieux ce C++, qui a clairement évité la récursion appelle
int fact(int x, int total=1)
for(; x>1; --x)
total*=x;
return total;
}
Le problème avec cela est que les types (et leur taille) en question sont totalement inconnus . Je pourrais transférer vers une pile interne, mais cela limiterait la taille totale des arguments. Je suppose que si j'ai fait quelque chose comme, 200 octets, alors c'est plus que n'importe quelle personne sensée voudrait transférer de toute façon. À votre santé. – Puppy
@DeadMG, pour traiter des types arbitraires inconnus au moment de la compilation, l'approche habituelle consiste à passer _pointers_ (par exemple, dans la machine virtuelle CPython, pointeurs sur 'PyObject') - ou, de manière équivalente, références, si votre langage d'implémentation n'utilise pas de pointeurs . Ensuite, la taille de ce qui se passe sur et hors de la pile est parfaitement connue - 'sizeof (quel que soit *)', par exemple, 4 octets par objet dans une machine 32 bits. –
Si je ne stocke que des pointeurs sur la pile, où diable vais-je mettre ce qu'ils pointent? – Puppy