Files
libasm/srcs/bonus/ft_list_remove_if.s

109 lines
1.4 KiB
ArmAsm

global ft_list_remove_if
extern free
section .text
;this function remove an element from a list, set the previous element to the next
; the element to remove is in rax
; the previouse element is in r8
; the pointer to the start of the list is in rdi
remove_element:
push rsi
mov rsi, [rax + 8] ; save cur->next in rsi
call call_free_elem
test r8, r8
jz .first_elem ;if it's the first element, skip setting prev
mov [r8 + 8], rsi ; prev->next = rsi
jmp .remove_element_end
.first_elem:
mov [rdi], rsi ;set list start to rsi
.remove_element_end:
mov rax, rsi ; set cur element to rsi;
pop rsi
ret
;wants the element that needs to be freed in rax
call_free_elem:
push rdi
push rsi
push rdx
push rcx
push r8
push rax
mov rdi, [rax]
sub rsp, 8
call rcx ; call remove
add rsp, 8
pop rdi
call free wrt ..plt
pop r8
pop rcx
pop rdx
pop rsi
pop rdi
ret
ft_list_remove_if:
test rdi, rdi
jz .end
test rdx, rdx
jz .end
test rcx, rcx
jz .end
xor r8, r8
mov rax, [rdi]
.loop:
test rax, rax
jz .end
push rax
push rdi
push rsi
push rdx
push rcx
push r8
mov rdi, [rax]
sub rsp, 8
call rdx
add rsp, 8
test eax, eax
pop r8
pop rcx
pop rdx
pop rsi
pop rdi
jnz .loop_end ;if call to rdx returned zero, don't remove
pop rax
sub rsp, 8
call remove_element
add rsp, 8
jmp .loop
.loop_end:
pop rax
mov r8, rax
mov rax, [rax + 8]
jmp .loop
.end:
ret