针对x86_64的Lisp编译器的递归函数定义

问题描述

我正在编写针对x86_64的Lisp编译器。到目前为止,大多数类型的功能都可以使用,但是我现在遇到了障碍。典型的Lisp阶乘函数给了我一个分割错误。查看代码似乎完全可以,但事实并非如此!使用GDB跟踪我的代码后,即使rax为1,递归过程似乎也继续进行。我追踪到-4。有人知道为什么会这样吗?

这是我的编译方式:

clang -O0 -mstackrealign -masm=intel test.asm(在MacOS上使用GAS。)

(define (factorial x)
    (if (= x 1) 1
        (* x (factorial (- x 1)))))

(define result (factorial 5))

我在下面包括了我要调用的外部函数的定义。

    .global _main
    .text
_main:
    push 5  # push argument to factorial
    call factorial
    add rsp,8  # discard 1 local argument
    mov [x + rip],rax
    mov rdi,0
    mov rax,0x2000001
    syscall
factorial:
    push rbp
    mov rbp,rsp
    push 1  # push argument to =
    push [rbp + 16]  # push argument to =
    call equal
    add rsp,16  # discard 2 local arguments
    cmp rax,1  # is true?
    je true_1  # true branch
    jmp false_2  # false branch
    true_1:
    mov rax,1
    jmp end_3
    false_2:
    push 1  # push argument to -
    push [rbp + 16]  # push argument to -
    call minus
    add rsp,16  # discard 2 local arguments
    push rax  # result of -
    call factorial
    add rsp,8  # discard 1 local argument
    push rax  # result of factorial
    push [rbp + 16]  # push argument to *
    call multiply
    add rsp,16  # discard 2 local arguments
    jmp end_3
    end_3:
    mov rsp,rbp
    pop rbp
    ret

    .data
x:
    .quad 0
.macro operator mnemonic
push rbp
mov rbp,rsp

mov rax,[rbp + 24]
\mnemonic rax,[rbp + 16]

mov rsp,rbp
pop rbp
ret
.endm

minus: operator sub
multiply: operator imul
equal:
    push rbp
    mov rbp,rsp
    mov rsi,[rbp + 16]
    cmp rsi,[rbp + 24]
    je equal_true
    mov rax,0
    jmp equal_end
    equal_true:
        mov rax,1
        jmp equal_end
    equal_end:
        mov rsp,rbp
        pop rbp
        ret

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)