我自学汇编语言已经有几个月了,我已经到了摆弄链表的地步。以下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
链接。
1条答案
按热度按时间kdfy810k1#
好吧,我的代码有几个问题:在一些函数调用之前,我没有保存
r10
和r11
寄存器,这可能改变了它们的值。尽管如此,我仍然有点困惑,因为gdb仍然显示与代码有错误时相同的地址。然后,我应该在call free wrt ..plt
之后添加jmp .rm_loop
,否则如果要删除前一个节点,函数将跳过一个节点。至此,我提供的代码中的bug已经修复。还有一个错别字:我尝试使用rbp
而不是rsp
访问堆栈变量。就像我说的,代码中没有错别字,但我会在这里留下这个作为提醒:)