summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Gayot <duskcoder@gmail.com>2014-02-17 01:49:25 +0100
committerOlivier Gayot <duskcoder@gmail.com>2014-02-17 01:49:25 +0100
commit45376fd12154eac48069a5c19c4e3b268f27f98a (patch)
tree6ea705652379ec382f2ca18198f842d58a4225e7
parent10feec2708dadeb3adfe81844b1766691b9d058a (diff)
add the function list_insert.HEADmaster
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]
-rw-r--r--list.asm80
-rw-r--r--public.asm4
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
@@ -141,6 +147,64 @@ list_append: ;; {{{
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: ;; {{{
enter 0x14, 0
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