aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE21
-rw-r--r--Makefile6
-rw-r--r--README.md18
-rw-r--r--ft_list_push_front.s27
-rw-r--r--ft_list_remove_if.s88
-rw-r--r--ft_list_size.s6
-rw-r--r--ft_list_sort.s155
-rw-r--r--ft_read.s30
-rw-r--r--ft_write.s32
-rw-r--r--main.c154
10 files changed, 420 insertions, 117 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..476120d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 HappyTramp
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile b/Makefile
index 7a3282e..881ccc6 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
# By: cacharle <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2019/11/22 02:56:22 by cacharle #+# #+# #
-# Updated: 2019/11/25 04:46:29 by cacharle ### ########.fr #
+# Updated: 2020/04/12 19:53:58 by charles ### ########.fr #
# #
# **************************************************************************** #
@@ -26,8 +26,8 @@ endif
NAME = libasm.a
ASMSRC = ft_strlen.s ft_strcpy.s ft_strcmp.s ft_write.s ft_read.s \
- ft_strdup.s ft_atoi_base.s #ft_list_push_front.s \
- # ft_list_size.s ft_list_sort.s ft_list_remove_if.s
+ ft_strdup.s ft_atoi_base.s ft_list_push_front.s \
+ ft_list_size.s ft_list_sort.s ft_list_remove_if.s
ASMOBJ = $(ASMSRC:.s=.o)
TESTNAME = runtest
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2bd0427
--- /dev/null
+++ b/README.md
@@ -0,0 +1,18 @@
+# libasm
+
+libasm project of school 42.
+
+## Test
+
+Clone the test [repository](https://github.com/HappyTramp/libasm_test) next to this project folder.
+
+```
+.
+|- libasm
+|- libasm_test
+```
+
+```
+cd libasm_test
+make runbonus
+```
diff --git a/ft_list_push_front.s b/ft_list_push_front.s
index 686ee10..320c49c 100644
--- a/ft_list_push_front.s
+++ b/ft_list_push_front.s
@@ -10,13 +10,28 @@
; ;
; **************************************************************************** ;
-global _ft_list_push_front
+extern _malloc
+
+global ft_list_push_front
; void ft_list_push_front(t_list **begin_list, void *data);
-_ft_list_push_front:
- cmp rdi, 0
- je FT_LIST_PUSH_FRONT_END
- mov [rsi + 8], [rdi]
- mov [rdi], rsi
+ft_list_push_front:
+ cmp rdi, 0
+ je FT_LIST_PUSH_FRONT_END
+
+ push rdi
+ push rsi
+ xor rdi, rdi
+ mov edi, 16
+ call _malloc
+ pop rsi
+ pop rdi
+ cmp rax, 0
+ je FT_LIST_PUSH_FRONT_END
+
+ mov qword [rax + 0], rsi
+ mov r10, [rdi]
+ mov [rax + 8], r10
+ mov [rdi], rax
FT_LIST_PUSH_FRONT_END:
ret
diff --git a/ft_list_remove_if.s b/ft_list_remove_if.s
index 9ae6ba5..40e2415 100644
--- a/ft_list_remove_if.s
+++ b/ft_list_remove_if.s
@@ -10,49 +10,85 @@
; ;
; **************************************************************************** ;
-global _ft_list_remove_if
+global ft_list_remove_if
+
+extern _free
+
+%define NULL 0x0
+
+%macro EXTERN_FUNCTION_SAVE 0
+ push rdi
+ push rsi
+ push rdx
+ push rcx
+%endmacro
+
+%macro EXTERN_FUNCTION_SAVE_END 0
+ pop rcx
+ pop rdx
+ pop rsi
+ pop rdi
+%endmacro
; ft_list_remove_if(t_list **begin_list, void *data_ref,
-; int (*cmp)(), void (*free_fct)(void *))
+; int (*cmp)(void *data, void *data_ref),
+; void (*free_fct)(void *))
+ft_list_remove_if:
+ ; t_list *saved_next
-_ft_list_remove_if:
+ ; === prolog ===
+ push rbp
+ mov rbp, rsp
sub rsp, 8
- cmp rdi, 0x0
+ ; === base condition ===
+ cmp rdi, NULL
je FT_LIST_REMOVE_IF_END
- cmp [rdi], 0x0
+ cmp qword [rdi], NULL
je FT_LIST_REMOVE_IF_END
- push rdi
- mov rdi, [rdi] + 8 ;&(*begin_list)->val
- call rdx
- pop rdi
- cmp rax, 0x0
+ ; === compare (*begin_list)->data and data_ref
+ EXTERN_FUNCTION_SAVE
+ mov rdi, [rdi]
+ mov rdi, [rdi + 0]
+ call rdx ; cmp((*begin_list)->data, data_ref)
+ EXTERN_FUNCTION_SAVE_END
+ cmp rax, 0
je FT_LIST_REMOVE_IF_REMOVE
-
- mov rdi, [rdi] + 8
- call _ft_list_remove_if
- add rsp, 8
- ret
-
-FT_LIST_REMOVE_IF_REMOVE:
- mov [rsp], [rdi] + 8 ; saved_next = (*begin_list)->next
-
+ ; === next element ===
push rdi
- mov rdi, [[rdi]]
- call rcx ; free_fct((*begin_list)->data)
+ mov rdi, [rdi]
+ lea rdi, [rdi + 8]
+ call ft_list_remove_if
pop rdi
+ jmp FT_LIST_REMOVE_IF_END
- push rdi
+ ; === remove head and go next ===
+FT_LIST_REMOVE_IF_REMOVE:
+ mov rax, [rdi] ; rax = *begin_list
+ mov rax, [rax + 8] ; rax = rax->next
+ mov [rbp - 8], rax ; saved_next = (*begin_list)->next
+
+ push rdi ; strange behavior
+ EXTERN_FUNCTION_SAVE
mov rdi, [rdi]
- call _free ; free(*begin_list)
+ mov rdi, [rdi + 0]
+ call rcx ; free_fct((*begin_list)->data)
+ EXTERN_FUNCTION_SAVE_END
pop rdi
- mov [rdi], [rsp] ; *begin_list = saved_next
+ EXTERN_FUNCTION_SAVE
+ mov rdi, [rdi]
+ call _free ; free(*begin_list)
+ EXTERN_FUNCTION_SAVE_END
- call _ft_list_remove_if
+ mov rax, [rbp - 8]
+ mov [rdi], rax
+ call ft_list_remove_if
FT_LIST_REMOVE_IF_END:
- add rsp, 8
+ ; === epilog ===
+ mov rsp, rbp
+ pop rbp
ret
diff --git a/ft_list_size.s b/ft_list_size.s
index ad89999..5367a17 100644
--- a/ft_list_size.s
+++ b/ft_list_size.s
@@ -10,10 +10,10 @@
; ;
; **************************************************************************** ;
-global _ft_list_size
+global ft_list_size
; int ft_list_size(t_list *begin_list);
-_ft_list_size:
+ft_list_size:
xor eax, eax
FT_LIST_SIZE_LOOP:
cmp rdi, 0
@@ -21,5 +21,5 @@ FT_LIST_SIZE_LOOP:
inc eax
mov rdi, [rdi + 8]
jmp FT_LIST_SIZE_LOOP
-FT_LIST_SIZE_END
+FT_LIST_SIZE_END:
ret
diff --git a/ft_list_sort.s b/ft_list_sort.s
index 23924e1..b077b89 100644
--- a/ft_list_sort.s
+++ b/ft_list_sort.s
@@ -10,108 +10,117 @@
; ;
; **************************************************************************** ;
-global _ft_list_sort
-
-; void ft_list_sort(t_list **begin_list, int (*cmp)());
-_ft_list_sort:
- ; t_list *fast
- ; t_list *slow
- ; t_list *middle
- sub rsp, 24
-
- cmp rdi, 0x0
- je FT_LIST_SORT_END
- cmp [rdi], 0x0
- je FT_LIST_SORT_END
- cmp [[rdi] + 8], 0x0 ; use tmp register
- je FT_LIST_SORT_END
-
- mov [rsp], [[rdi] + 8]
- mov [rsp + 8], [rdi]
-FT_GET_MIDDLE_LOOP:
- mov [rsp], [rsp + 8]
- cmp [rsp], 0x0
- je FT_GET_MIDDLE_LOOP_END
- mov [rsp], [rsp + 8]
- mov [rsp + 8], [[rsp + 8] + 8] ; i want c pointers back plz
-FT_GET_MIDDLE_LOOP_END:
- mov [rsp + 16], [[rsp + 8] + 8]
- mov [[rsp + 8] + 8], 0x0
+global ft_list_sort
+
+%define NULL 0x0
+
+; void ft_list_sort(t_list **begin_list, int (*cmp)(void*, void*));
+ft_list_sort:
+ ; t_list *slow : rax = *begin_list
+ ; t_list *fast : rbx = (*begin_list)->next
+ ; t_list *middle : rsp + 0
+
+ ; === base condition ===
+ cmp rdi, NULL
+ je FT_LIST_SORT_END ; if begin_list == NULL return
+ mov rax, [rdi]
+ cmp rax, NULL
+ je FT_LIST_SORT_END ; if *begin_list == NULL return
+ mov rbx, [rax + 8]
+ cmp rbx, NULL
+ je FT_LIST_SORT_END ; if (*begin_list)->next == NULL return
+
+ ; === find list middle loop ===
+FT_LIST_SORT_MIDDLE_LOOP: ; do {
+ mov rbx, [rbx + 8] ; fast = fast->next
+ cmp rbx, NULL
+ je FT_LIST_SORT_MIDDLE_LOOP_END ; if fast == NULL break
+ mov rbx, [rbx + 8] ; fast = fast->next
+ mov rax, [rax + 8] ; slow = slow->next
+ cmp rbx, NULL
+ jne FT_LIST_SORT_MIDDLE_LOOP ; } while (fast != NULL)
+FT_LIST_SORT_MIDDLE_LOOP_END:
+
+ ; create a stack frame for local variable to store middle address
+ push rbp
+ mov rbp, rsp
+ sub rsp, 8
- push rdi
- call _ft_list_sort
- pop rdi
+ ; store middle in [rbp - 8]
+ mov rcx, [rax + 8]
+ mov [rbp - 8], rcx
+ mov qword [rax + 8], NULL ; slow->next = NULL
+ ; === sorting both child list ===
push rdi
- mov rdi, [rsp + 16]
- call _ft_list_sort
+ push rsi
+ call ft_list_sort ; ft_list_sort(begin_list, cmp)
+ lea rdi, [rbp - 8]
+ call ft_list_sort ; ft_list_sort(&middle, cmp)
+ pop rsi
pop rdi
+ ; === merging sorted child ===
push rdi
push rsi
- mov rdx, rsi
- mov rdi, [rdi]
- mov rsi, [rsp + 16]
- call _merge_sorted_list
+ mov rdi, [rdi] ; arg_1 = *begin_list
+ mov rdx, rsi ; arg_3 = cmp
+ mov rsi, [rbp - 8] ; arg_2 = middle
+ call _st_merge_sorted_list
pop rsi
pop rdi
+ mov [rdi], rax ; *begin_list = st_merge_sorted_list(...);
- mov [rdi], rax
-
- add rsp, 24
+ ; restoring stack frame
+ mov rsp, rbp
+ pop rbp
FT_LIST_SORT_END:
ret
-
-; t_list *merge_sorted_list(t_list* l1, t_list* l2, int (*cmp)())
-_merge_sorted_list:
- sub rsp, 8
-
- cmp rdi, 0x0
- je MERGE_SORTED_LIST_RETURN_L2
- cmp rsi, 0x0
- je MERGE_SORTED_LIST_RETURN_L1
+; t_list *st_merge_sorted_list(t_list* l1, t_list* l2, int (*cmp)(void*, void*))
+_st_merge_sorted_list:
+ cmp rdi, NULL
+ je MERGE_SORTED_LIST_RETURN_L2 ; if l1 == NULL return l2
+ cmp rsi, NULL
+ je MERGE_SORTED_LIST_RETURN_L1 ; if l2 == NULL return l1
push rdi
push rsi
- mov rdi, [rdi]
- mov rsi, [rsi]
- call rdx ; cmp
+ push rdx
+ mov rdi, [rdi + 0] ; l1->data
+ mov rsi, [rsi + 0] ; l2->data
+ xor rax, rax
+ call rdx ; cmp
+ pop rdx
pop rsi
pop rdi
- cmp rax, 0x0
- jl L1_LT_L2
+ cmp eax, 0
+ jl MERGE_SORTED_LIST_L1_LT_L2
-; L1_GE_L2
- mov rsp, rsi
+ ; if l1 >= l2
+ push rsi ; save l2
+ mov rsi, [rsi + 8] ; l2 = l2->next
+ call _st_merge_sorted_list ; merge_sorted_list(l1, l2->next, cmp)
+ pop rsi ; restore rsi
+ mov [rsi + 8], rax
+ mov rax, rsi
+ jmp MERGE_SORTED_LIST_END
+ ; else
+MERGE_SORTED_LIST_L1_LT_L2:
push rdi
- push rsi
mov rdi, [rdi + 8]
- call _merge_sorted_list
- pop rsi
+ call _st_merge_sorted_list ; merge_sort_list(l1->next, l2, cmp)
pop rdi
- mov [rsp + 8], rax
+ mov [rdi + 8], rax
+ mov rax, rdi
jmp MERGE_SORTED_LIST_END
-L1_LT_L2:
- mov rsp, rdi
- push rdi
- push rsi
- mov rsi, [rsi + 8]
- call _merge_sorted_list
- pop rsi
- pop rdi
- mov [rsp + 8], rax
-
-MERGE_SORTED_LIST_END:
- mov rax, [rsp]
- add rsp, 8
- ret
MERGE_SORTED_LIST_RETURN_L1:
mov rax, rdi
ret
MERGE_SORTED_LIST_RETURN_L2:
mov rax, rsi
+MERGE_SORTED_LIST_END:
ret
diff --git a/ft_read.s b/ft_read.s
index 14824f5..a94cece 100644
--- a/ft_read.s
+++ b/ft_read.s
@@ -12,8 +12,36 @@
global ft_read
+%define F_GETFD 1
+%define SYSCALL_READ 0x2000003
+%define SYSCALL_FCNTL 0x200005c
+
; int ft_read(int, void*, size_t);
ft_read:
- mov rax, 0x2000003
+ cmp rdx, 0
+ je FT_READ_NO_SIZE
+ cmp rdi, 0
+ jl FT_READ_ERROR
+ cmp rsi, 0
+ je FT_READ_ERROR
+
+ push rdx
+ push rsi
+ xor rsi, rsi
+ mov esi, F_GETFD
+ mov rax, SYSCALL_FCNTL
+ syscall
+ pop rsi
+ pop rdx
+ cmp eax, 0
+ jne FT_READ_ERROR
+
+ mov rax, SYSCALL_READ
syscall
ret
+FT_READ_ERROR:
+ mov rax, -1
+ ret
+FT_READ_NO_SIZE:
+ xor rax, rax
+ ret
diff --git a/ft_write.s b/ft_write.s
index 2e3ba00..0761329 100644
--- a/ft_write.s
+++ b/ft_write.s
@@ -12,8 +12,36 @@
global ft_write
-; int ft_write(int, const void*, size_t);
+%define F_GETFD 1
+%define SYSCALL_WRITE 0x2000004
+%define SYSCALL_FCNTL 0x200005c
+
+; int ft_write(int rdi, const void *rsi, size_t rdx);
ft_write:
- mov rax, 0x2000004
+ cmp rdx, 0
+ je FT_WRITE_NO_SIZE
+ cmp rdi, 0
+ jl FT_WRITE_ERROR ; fd < 0
+ cmp rsi, 0
+ je FT_WRITE_ERROR ; buf == NULL
+
+ push rdx
+ push rsi
+ xor rsi, rsi
+ mov esi, F_GETFD
+ mov rax, SYSCALL_FCNTL
+ syscall
+ pop rsi
+ pop rdx
+ cmp eax, 0
+ jne FT_WRITE_ERROR
+
+ mov rax, SYSCALL_WRITE
syscall
ret
+FT_WRITE_ERROR:
+ mov rax, -1
+ ret
+FT_WRITE_NO_SIZE:
+ mov rax, 0
+ ret
diff --git a/main.c b/main.c
index 70713f7..dec671b 100644
--- a/main.c
+++ b/main.c
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/22 02:02:24 by cacharle #+# #+# */
-/* Updated: 2019/11/25 03:29:53 by cacharle ### ########.fr */
+/* Updated: 2020/04/12 19:51:04 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,6 +20,116 @@ typedef struct s_list
struct s_list *next;
} t_list;
+
+int*
+create_data_elem(int data)
+{
+ int *data_ptr = malloc(sizeof(int));
+ if (data_ptr == NULL)
+ return (NULL);
+ *data_ptr = data;
+ return data_ptr;
+}
+
+t_list*
+create_elem(int data)
+{
+ t_list *new = malloc(sizeof(t_list));
+ if (new == NULL)
+ return NULL;
+ if ((new->data = create_data_elem(data)) == NULL)
+ return (NULL);
+ new->next = NULL;
+ return new;
+}
+
+static void
+push_front(t_list **lst_ptr, t_list *new_front)
+{
+ if (lst_ptr == NULL || new_front == NULL)
+ return ;
+ new_front->next = *lst_ptr;
+ *lst_ptr = new_front;
+}
+
+static t_list*
+reverse(t_list *list)
+{
+ if (list == NULL || list->next == NULL)
+ return list;
+ t_list *tmp = reverse(list->next);
+ list->next->next = list;
+ list->next = NULL;
+ return tmp;
+}
+
+t_list*
+list_from_format(char *fmt)
+{
+ t_list *head = NULL;
+
+ while (fmt != NULL && *fmt)
+ {
+ int n = (int)strtol(fmt, &fmt, 10);
+ t_list *elem = create_elem(n);
+ push_front(&head, elem);
+ }
+ return reverse(head);
+}
+
+t_list*
+list_dup(t_list *list)
+{
+ t_list *dup_head = NULL;
+
+ while (list != NULL)
+ {
+ t_list *tmp = create_elem(*(int*)list->data);
+ push_front(&dup_head, tmp);
+ }
+ return reverse(dup_head);
+}
+
+int
+list_cmp(t_list *l1, t_list *l2)
+{
+ if (l1 == NULL && l2 == NULL)
+ return 0;
+ if (l1 == NULL)
+ return -1;
+ if (l2 == NULL)
+ return 1;
+ if (l1->data == NULL)
+ return -1;
+ if (l2->data == NULL)
+ return 1;
+ if (*(int*)l1->data != *(int*)l2->data)
+ return *(int*)l1->data - *(int*)l2->data;
+ return list_cmp(l1->next, l2->next);
+}
+
+void
+list_print(t_list *list)
+{
+ while (list != NULL)
+ {
+ printf("[%d] -> ", *(int*)list->data);
+ list = list->next;
+ }
+ printf("(null)");
+}
+
+void
+list_destroy(t_list *list)
+{
+ if (list == NULL)
+ return ;
+ list_destroy(list->next);
+ if (list->data != NULL)
+ free(list->data);
+ free(list);
+}
+
int ft_strlen(char *);
char *ft_strcpy(char *dst, const char *src);
int ft_strcmp(const char *s1, const char *s2);
@@ -31,6 +141,26 @@ int ft_atoi_base(const char*, const char*);
void ft_list_push_front(t_list **begin_list, void *data);
int ft_list_size(t_list *begin_list);
void ft_list_sort(t_list **begin_list, int (*cmp)());
+void ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)(), void (*free_fct)(void*));
+
+int compar(void *a, void *b)
+{
+ printf("---\n");
+ printf("a = %p, b = %p\n", a, b);
+ printf("*a = %d, *b = %d\n", *(int*)a, *(int*)b);
+ int c = *(int*)a - *(int*)b;
+ printf("ret %d\n", c);
+ return c;
+}
+
+void free_fct(void *data)
+{
+ printf("free: %p\n", data);
+ printf("free data %d\n", *(int*)data);
+ free(data);
+ printf("end free\n");
+ fflush(stdout);
+}
int main()
{
@@ -66,12 +196,30 @@ int main()
/* printf("%d\n", h); */
/* printf("%s\n", h); */
/* free(h); */
- /* */
+
/* printf("%d\n", check_base("01")); */
/* printf("%d\n", ft_atoi_base(" \t\n\r\v\f\r 10\t0101001", "01")); */
- printf("%d\n", ft_atoi_base("01", ""));
/* printf("_%d_\n", ft_atoi_base(" 755x+", "01234567")); */
+
+ /* system("vmmap a.out"); */
+ /* t_list *a = list_from_format("-1 2 3 98 1234 12 123 4 123 -123 2 5 6 0 1 3 4"); */
+ /* t_list *a = list_from_format("1"); */
+ /* t_list *a = NULL; */
+ /* printf("%d: ", ft_list_size(a)); list_print(a); putchar('\n'); */
+ /* ft_list_sort(&a, compar); */
+ /* printf("%d: ", ft_list_size(a)); list_print(a); putchar('\n'); */
+
+ t_list *a = list_from_format("1 2 3 4 1 2 3 1");
+ int data_ref = 1;
+ printf("f: %p\n", a->data);
+ /* free(a->data); */
+ printf("%p\n", &data_ref);
+ list_print(a); putchar('\n');
+ ft_list_remove_if(&a, &data_ref, compar, free_fct);
+ list_print(a); putchar('\n');
+
+ list_destroy(a);
return 0;
}