I've been teaching myself assembly language for a few months now, and I got to the point where I was playing around with linked lists. The following x86_64 intel assembly function crashes (SEGV) when it tries to free a struct pointer, but the first free call succeeds. I should note that this code ran perfectly fine on my old Linux mint machine (I am now running Debian 12 but it also crashes on 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
Here is the definition of the struct:
typedef struct s_list
{
void *data;
struct s_list *next;
} t_list;
where data is always a malloc'ed pointer. I use strcmp
as cmp
and free
as free_fct
. I assemble with nasm:2.16.01
and then link with gcc:12.2.0
.