I've written the following factorial function which can use tail call recursion. I've added in putchar('x') just so I can see it is running:
#include <stdio.h>
int factorial(int n) {
    if (n > 0) {
        putchar('x');
        return n + factorial(n-1);
    } else 
        return 1;
}
And the compiler optimizes this to not use recursion (i.e., calling the function) but tail-call recursion (like a while loop). I was wondering if someone could explain the basics of how the tail-call assembly works in the above. The 'recursive part' of the assembly is the following:
.L3:
        movq    stdout(%rip), %rsi     // what is this line doing? I don't see `stdout` anywhere
        movl    $120, %edi             // why do we need to re-add 'x' every loop since static?
        addl    %ebx, %ebp
        call    putc
        subl    $1, %ebx
        jne     .L3
Compiler Explorer link is here.
 
    