izolveidon
izolveidon

Reputation: 89

Problem with recursive factorial in x86_64 Assembly

I'm new to this assembly language and I tried to do the following code on my own. The problem is that my code cannot calculate the factorial of a number correctly and it always shows 1 as an output in the terminal. I'd like to know the reason why it is not working.

.text

mystring1: .asciz "Assignment 4: recursion\nType any number to calculate the factorial of that number:\n"  # string for printing message
formatstr: .asciz "%ld"                   # format string for printing number
mystring2: .asciz "\n"                    # string for printing a new line

.global main  # make the main label visible  

main:

    pushq %rbp            # store the caller's base pointer
    movq %rsp, %rbp       # initialise the base pointer
    movq $0, %rax         # no vector registers in use for printf
    movq $mystring1, %rdi # load address of a string
    call printf           # call the printf subroutine
    call inout            # call the inout subroutine
    movq $0, %rax         # no vector registers in use for printf
    movq $mystring2, %rdi # load address of a string
    call printf
    jmp end

inout:

    pushq %rbp                  # push the base pointer
    movq %rsp, %rbp             # copy the stack pointer to rbp
    subq $16, %rsp              # reserve stack space for variable
    leaq -8(%rbp), %rsi         # load address of stack variable in rsi
    movq $formatstr, %rdi       # load first argument of scanf
    movq $0, %rax               # no vector registers in use for scanf
    call scanf                  # call scanf routine
    movq -8(%rbp), %rsi         # move the address of the variable to rsi
    call factorial
    movq $0, %rax               # no vector registers in use for printf
    movq $formatstr, %rdi       # move the address formatstring to rdi
    call printf                 # print the result
    movq %rbp, %rsp             # copy rbp to rsp
    popq %rbp                   # pop rbp from the stack
    ret                         # return from the subroutine

factorial:

    cmpq $1, %rsi
    jle factend
    pushq %rbx
    movq %rsi, %rbx
    subq $1, %rsi
    call factorial
    mulq %rbx
    popq %rbx
    ret

factend:

    movq $1, %rax
    ret

end:
    mov $0, %rdi # load program exit code
    call exit    # exit the program

The pseudocode of my code:

long rfact(long n)
{
     long result;
     if (n < = 1)
     {
        result = 1;
     }
     else
     {
        result = n * rfact(n - 1);
        return result;
     }
}

Upvotes: 0

Views: 607

Answers (1)

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32732

You're returning the result of your factorial in rax, but your caller is assuming that it is in rsi. The caller should move the result from rax to where it is needed (rsi in this case) right after the call to factorial returns.

Upvotes: 1

Related Questions