C语言 无法释放x86_64程序集中的结构指针(intel)

hmmo2u0o  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(156)

我自学汇编语言已经有几个月了,我已经到了摆弄链表的地步。以下x86_64 intel汇编函数在尝试释放结构指针时崩溃(SEGV),但第一次释放调用成功。我应该注意到,这段代码在我的旧Linux mint机器上运行得非常好(我现在运行的是Debian 12,但它在macos上也会崩溃)。

global _ft_list_remove_if
extern free

section .text

_ft_list_remove_if:

    push rbp
    mov rbp, rsp
    sub rsp, 32
    mov QWORD [rsp], rdi
    mov QWORD [rsp + 8], rsi
    mov QWORD [rsp + 16], rdx
    mov QWORD [rsp + 24], rcx

    mov r10, QWORD [rdi]            ; r10 = *begin_list

.rm_loop:
    cmp r10, 0
    je .restore_stack
    mov r11, QWORD [r10 + 8]        ; r11 = r10->next
    cmp r11, 0
    je .restore_stack

    mov rdx, QWORD [rsp + 16]       ; rdx = cmp
    mov rsi, QWORD [rsp + 8]        ; rsi = data_ref
    mov rdi, QWORD [r11]            ; rdi = r11->data
    push r10
    push r11
    call rdx

    pop r11
    pop r10
    cmp eax, 0
    jne .increment_ptr

    mov rax, QWORD [r11 + 8]        ; rax = r11->next
    mov QWORD [r10 + 8], rax        ; r10->next = rax

    ; remove
    mov rcx, QWORD [rsp + 24]       ; rcx = free_fct
    mov rdi, QWORD [r11]            ; rdi = r11->data
    push r10
    push r11
    call rcx

    pop r11
    mov rdi, r11
    push r11
    call free wrt ..plt
    pop r11
    pop r10

.increment_ptr:
    mov r10, QWORD [r10 + 8]        ; r10 = r10->next
    jmp .rm_loop

.restore_stack:
    add rsp, 32
    pop rbp

.endfunc:
    ret

字符串
下面是struct的定义:

typedef struct s_list
{
    void            *data;
    struct s_list   *next;
}   t_list;


其中数据总是被malloc的指针。我使用strcmp作为cmp,使用free作为free_fct。我用nasm:2.16.01组装,然后用gcc:12.2.0链接。

kdfy810k

kdfy810k1#

好吧,我的代码有几个问题:在一些函数调用之前,我没有保存r10r11寄存器,这可能改变了它们的值。尽管如此,我仍然有点困惑,因为gdb仍然显示与代码有错误时相同的地址。然后,我应该在call free wrt ..plt之后添加jmp .rm_loop,否则如果要删除前一个节点,函数将跳过一个节点。至此,我提供的代码中的bug已经修复。还有一个错别字:我尝试使用rbp而不是rsp访问堆栈变量。就像我说的,代码中没有错别字,但我会在这里留下这个作为提醒:)

相关问题