首页 > 解决方案 > x86_64 程序集中的递归阶乘问题

问题描述

我是这种汇编语言的新手,我尝试自己编写以下代码。问题是我的代码无法正确计算数字的阶乘,并且始终在终端中显示 1 作为输出。我想知道它不起作用的原因。

.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

我的代码的伪代码:

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

标签: recursionassemblyx86-64att

解决方案


您正在返回您的阶乘结果 in rax,但您的调用者假设它在rsi. 调用者应在调用返回后立即将结果从rax需要的位置(rsi在这种情况下)移动factorial


推荐阅读