From 45376fd12154eac48069a5c19c4e3b268f27f98a Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Mon, 17 Feb 2014 01:49:25 +0100 Subject: add the function list_insert. the function inserts a new element at the position specified in its third argument. example: list_clear(&list); list_insert(&list, 2, 0); list_insert(&list, 1, 0); list_insert(&list, 3, 2); list_insert(&list, 0, 0); the list will contain [0, 1, 2, 3] --- list.asm | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- public.asm | 4 ++++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/list.asm b/list.asm index 8932eaf..20e6688 100644 --- a/list.asm +++ b/list.asm @@ -95,22 +95,28 @@ list_clear: ;; {{{ ret ;; }}} -list_append: ;; {{{ - - enter 0x18, 0 - - mov [rsp], rdi - mov [rsp + 8], rsi +%macro rethrow_create_element 0 mov rdi, elem_t_size call malloc test rax, rax - jne .malloc_succeed + jne %%malloc_succeed mov rax, -1 jmp .end - .malloc_succeed: + %%malloc_succeed +%endmacro + +list_append: ;; {{{ + + enter 0x18, 0 + + mov [rsp], rdi + mov [rsp + 8], rsi + + rethrow_create_element + ; set the new element mov rsi, QWORD [rsp + 8] mov QWORD [rax + elem_t.next], 0 @@ -140,6 +146,64 @@ list_append: ;; {{{ leave ret +;; }}} +list_insert: ;; {{{ + + enter 0, 0 + + cmp edx, DWORD [rdi + list_t.size] + jg .error + + inc DWORD [rdi + list_t.size] + + push rdx + push rsi + push rdi + rethrow_create_element + pop rdi + pop rsi + pop rcx + + ; set the element + mov QWORD [rax + elem_t.value], rsi + + test ecx, ecx + jnz .insert + + ; this will be the first element + mov r8, QWORD [rdi + list_t.first] + mov QWORD [rax + elem_t.next], r8 + mov QWORD [rdi + list_t.first], rax + + jmp .success + + ; this is not the first element + .insert: + mov rdi, QWORD [rdi + list_t.first] + + .loop: + dec ecx + test ecx, ecx + jz .loop_ended + mov rdi, QWORD [rdi + elem_t.next] + jmp .loop + + .loop_ended: + mov r8, QWORD [rdi + elem_t.next] + mov QWORD [rax + elem_t.next], r8 + mov QWORD [rdi + elem_t.next], rax + + .success: + xor rax, rax + jmp .end + + .error: + mov rax, -1 + + .end: + leave + ret + ;; }}} list_apply: ;; {{{ diff --git a/public.asm b/public.asm index 0a90fe8..f4c216f 100644 --- a/public.asm +++ b/public.asm @@ -40,6 +40,10 @@ global list_clear:function ;; otherwise (on success), $rax will be set to 0 global list_append:function +;; like list_append but instead of adding at the end of the list, this +;; function adds at the position $rdx +global list_insert:function + ;; for every element in the list stored at address $rdi, call the function ;; pointed to by $rsi with the value of the current element. global list_apply:function -- cgit v1.2.3