/* factn.s - recursive factorial with command-line arg */ /* function main that calls fact(atoi(argv[1])) and prints the result */ /* recall header of main: main(int argc, char **argv) * so 2nd argument argv is an array of strings and can be found in rsi * argv[1] is 2nd element, so it's 8(%rsi) */ .globl main main: push %rbp /* create stack frame */ movq %rsp, %rbp push %rbx subq \$8, %rsp /* align stack to multiples of 16 */ movq 8(%rsi), %rdi /* get argv[1] */ call atoi /* n = atoi(argv[1]) */ movq %rax, %rbx /* store n in local variable */ movq %rax, %rdi call fact /* call fact(n) */ movq \$mystr, %rdi /* arg1 = mystr */ movq %rbx, %rsi /* arg2 = n */ movq %rax, %rdx /* arg3 = return value of fact */ call printf /* call printf(mystr, n, result) */ xorl %eax, %eax /* return 0 */ addq \$8, %rsp /* remove stack frame */ pop %rbx pop %rbp ret /* recursive function fact to compute the factorial * equivalent to the following C function: * * long fact(long n) { * long n1 = n-1; * if (n1 == 0) * return 1; * else * return n * fact(n1); * } */ fact: push %rbp /* create stack frame */ movq %rsp, %rbp push %rbx /* save rbx (used to hold n) */ movq %rdi, %rbx /* store n */ decq %rdi /* n1-- */ jz basecase /* if 0, goto basecase */ call fact /* call fact(n1) */ imulq %rbx, %rax /* multiply result by n */ jmp end basecase: movq \$1, %rax /* return 1 */ end: pop %rbx /* restore rbx */ pop %rbp /* remove stack frame */ ret .section .rodata mystr: .string "fact(%d) = %ld\n"