diff --git a/Makefile b/Makefile index ba5f71c..3a05232 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: rparodi +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2023/11/12 11:05:05 by rparodi #+# #+# # -# Updated: 2025/12/13 13:27:57 by rparodi ### ########.fr # +# Updated: 2025/12/28 19:40:32 by rparodi ### ########.fr # # # # **************************************************************************** # @@ -39,6 +39,7 @@ OBJ_BONUS = $(addprefix $(OBJDIRNAME)/,$(SRC_BONUS:.s=.o)) SRC = src/ft_strlen.s \ src/ft_strcmp.s \ src/ft_strcpy.s \ + src/ft_strdup.s \ src/ft_write.s \ src/ft_read.s diff --git a/includes/libasm.h b/includes/libasm.h index 4b9378b..9744e6a 100644 --- a/includes/libasm.h +++ b/includes/libasm.h @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/12/12 14:02:08 by rparodi #+# #+# */ -/* Updated: 2025/12/13 13:18:50 by rparodi ### ########.fr */ +/* Updated: 2025/12/28 19:42:43 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ #include #include +char *ft_strdup(char *s); char *ft_strcpy(char *dest, const char *src); int ft_strcmp(const char *s1, const char *s2); size_t ft_strlen(char *s); diff --git a/src/ft_read.s b/src/ft_read.s index 111e5bb..5eb489c 100644 --- a/src/ft_read.s +++ b/src/ft_read.s @@ -1,4 +1,5 @@ segment .note.GNU-stack + extern __errno_location section .text @@ -6,6 +7,7 @@ section .text ft_read: cmp rsi, 0 ; check if the buffer is NULL + mov rax, -1 ; set the return value to -1 (for error) (UB) je .exit ; if true go to exit mov rax, 0 ; syscall 0 is for read syscall ; call the system call read diff --git a/src/ft_strcpy.s b/src/ft_strcpy.s new file mode 100644 index 0000000..305e699 --- /dev/null +++ b/src/ft_strcpy.s @@ -0,0 +1,23 @@ +segment .note.GNU-stack + +section .text + global ft_strcpy + +ft_strcpy: + mov rax, rdi ; dest is the return value + cmp rdi, 0 ; check if dest is NULL + je .exit ; if true return NULL + cmp rsi, 0 ; check if src is NULL + je .exit ; if true return NULL + xor ecx, ecx ; index set to 0 + +.loop: + mov dl, BYTE [rsi + rcx] ; take the value of src + mov BYTE [rax + rcx], dl ; copy the value of src in dst + cmp dl, 0 ; check if the null byte is the last copied + je .exit ; return if it was the last byte + inc rcx ; increment the index + jmp .loop ; restart the loop again + +.exit: + ret ; return the rax (dest) value diff --git a/src/ft_strdup.s b/src/ft_strdup.s new file mode 100644 index 0000000..2bd7fa4 --- /dev/null +++ b/src/ft_strdup.s @@ -0,0 +1,27 @@ +segment .note.GNU-stack + +extern ft_strcpy +extern ft_strlen +extern malloc + +section .text + global ft_strdup + +ft_strdup: + push rbx ; save rbx + cmp rdi, 0 ; check s is NULL + je .exit ; exit (with restore of rbx) if true + mov rbx, rdi ; save rdi value in rbx + call ft_strlen ; call ft_strlen on rdi + lea rdi, [rax + 1] ; calculation of the malloc size + call malloc ; malloc is called return value on rax + test rax, rax ; check the return value of malloc + je .exit ; exit (with restore of rbx) if true + mov rdi, rax ; set the dest string (for ft_strcpy) + mov rsi, rbx ; set the source string (for ft_strcpy) + pop rbx ; restore rbx + jmp ft_strcpy ; call ft_strcpy + +.exit: + pop rbx ; restore rbx + ret ; return rax (NULL) diff --git a/src/ft_write.s b/src/ft_write.s index cd27233..ec756a4 100644 --- a/src/ft_write.s +++ b/src/ft_write.s @@ -1,4 +1,5 @@ segment .note.GNU-stack + extern __errno_location section .text diff --git a/test/main.c b/test/main.c index c40690a..ad5a8e0 100644 --- a/test/main.c +++ b/test/main.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/12/12 14:02:17 by rparodi #+# #+# */ -/* Updated: 2025/12/13 13:30:29 by rparodi ### ########.fr */ +/* Updated: 2026/01/13 12:12:01 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ #include "_internal_test.h" #include #include +#include #include #include #include @@ -121,6 +122,30 @@ static void _test_strcpy(void) putchar('\n'); } +static void _test_strdup(void) +{ + printf("\n%sTesting '%sstrdup%s'%s\n", CLR_YELLOW, CLR_BLUE, CLR_YELLOW, RESET); + ft_strdup(NULL); + printf("%s✔%s ", CLR_GREEN, RESET); + for (int i = 0; strs[i]; i++) + { + char buf_orig[8192]; + char buf_home[8192]; + memset(buf_orig, 0, sizeof(buf_orig)); + memset(buf_home, 0, sizeof(buf_home)); + char *ret_orig = strdup(strs[i]); + char *ret_home = ft_strdup(strs[i]); + if (strcmp(ret_orig, ret_home) == 0 && strcmp(buf_orig, buf_home) == 0) + printf("%s✔%s", CLR_GREEN, RESET); + else + dprintf(2, "\t%s✘%s", CLR_RED, RESET); + putchar(' '); + free(ret_orig); + free(ret_home); + } + putchar('\n'); +} + static void _test_write(void) { int original, homemade; @@ -171,8 +196,8 @@ static void _test_read(void) int original, homemade; int err_original, err_homemade; int test_file; - char buf_orig[100]; - char buf_home[100]; + char buf_orig[8192]; + char buf_home[8192]; printf("\n%sTesting '%sft_read%s'%s\n", CLR_YELLOW, CLR_BLUE, CLR_YELLOW, RESET); @@ -222,6 +247,7 @@ int main(int argc, char *argv[]) _test_strcpy, _test_write, _test_read, + _test_strdup, NULL }; char *func_name[] = { @@ -230,6 +256,7 @@ int main(int argc, char *argv[]) "strcpy", "write", "read", + "strdup", NULL };