Я думаю, что вы смотрите на это неправильно. Вместо того, чтобы выталкивать старые переменные из стека и затем выталкивать новые, просто переназначьте уже существующие (осторожно). Это примерно такая же оптимизация, которая произошла бы, если бы вы переписали код, чтобы он стал эквивалентным итерационным алгоритмом.
Для этого кода:
int fact(int x, int total=1) {
if (x == 1)
return total;
return fact(x-1, total*x);
}
будет
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"
Нет необходимости вставлять или вставлять что-либо в стек, просто переназначить.
Очевидно, что это может быть дополнительно оптимизировано, если поставить условие выхода вторым, что позволит нам пропустить переход, что приведет к меньшему количеству операций.
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
Опять же, эта «сборка» лучше отражает этот C ++, который явно избегает рекурсивных вызовов
int fact(int x, int total=1)
for( ; x>1; --x)
total*=x;
return total;
}