为什么我的 x86 链表函数会抛出段错误?

Why is my x86 linked-list function throwing a segfault?

我一直在写代码,一整天都在尝试在x86汇编中得到一个链表。没有任何效果,这非常令人沮丧。我正在尝试制作一个包含元素 1、2 和 3 的元素。GDB 告诉我它在 endret 语句中出现段错误,但没有提供更多信息。谁能帮我这个?我正在用 Clang 组装 Mac。

这是我的代码:

    .global _main
    .text

/*
r12: result
r14: number of elements left in list
r15: stack offset for accessing arguments
*/

make_list:
    # # # # #
    push rbp
    mov rbp, rsp
    # # # # #
    mov rdi, [rbp + r15]
    mov qword ptr [rax], rdi  # assign first_node.head
    lea r13, [rax + 8]  # store address of first_node.tail
    # # # # #
    mov rdi, 16
    sub rsp, 8
    call _malloc
    add rsp, 8
    # # # # #
    add r15, 8
    sub r14, 1
    # # # # #
    mov rdi, [rbp + r15]
    mov qword ptr [r13], rdi  # assign second_node.head
    # # # # #
    cmp r14, 0
    je end
    # # # # #
    mov rdi, 16
    sub rsp, 8
    call _malloc
    add rsp, 8
    # # # # #
    jmp make_list  # assign second_node.tail to an argument
    # # # # #
    end:
        mov qword ptr [r13 + 8], 0  # second_node.tail = NULL
        mov rsp, rbp
        pop rbp
        ret
    # # # # #

_main:
    # # # # #
    mov rdi, 16
    sub rsp, 8
    call _malloc
    add rsp, 8
    lea r12, [rax]
    # # # # #
    mov r14, 3
    mov r15, 16
    # # # # #
    push 3
    push 2
    push 1
    # # # # #
    call make_list
    add rsp, 24
    # # # # #
    mov rdi, 0
    mov rax, 0x2000001
    syscall
    # # # # #

jmp make_list 指令不正确。您不想跳转到函数的开头,您再次 rbp,而是跳转到函数中途的某个地方,在完成所有设置之后。

ret 之前未弹出的多个 push rbp 指令导致指令指针在其中获取无效值,从而导致您的设置错误。