109 lines
1.4 KiB
ArmAsm
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
|