diff --git a/libftasm/.gitignore b/libftasm/.gitignore new file mode 100644 index 00000000..4be147d0 --- /dev/null +++ b/libftasm/.gitignore @@ -0,0 +1,2 @@ +test +libfts.a diff --git a/libftasm/Makefile b/libftasm/Makefile new file mode 100644 index 00000000..d932a4ba --- /dev/null +++ b/libftasm/Makefile @@ -0,0 +1,110 @@ +#* ************************************************************************** *# +#* *# +#* ::: :::::::: *# +#* Makefile :+: :+: :+: *# +#* +:+ +:+ +:+ *# +#* By: wescande +#+ +:+ +#+ *# +#* +#+#+#+#+#+ +#+ *# +#* Created: 2016/08/29 21:32:58 by wescande #+# #+# *# +#* Updated: 2016/12/24 02:14:21 by wescande ### ########.fr *# +#* *# +#* ************************************************************************** *# + +SHELL := bash + +NAME = libfts.a +NASM = nasm + +UNAME_S = $(shell uname -s) +ifeq ($(UNAME_S),Linux) + FLAGS_ASM = -g\ + -f elf64\ + -D READ=0x0000000\ + -DWRITE=0x0000001 +endif +ifeq ($(UNAME_S),Darwin) + FLAGS_ASM = -g\ + -f macho64\ + -D READ=0x2000003\ + -DWRITE=0x2000004 +endif + + +LEN_NAME = `printf "%s" $(NAME) |wc -c` +DELTA = $$(echo "$$(tput cols)-31-$(LEN_NAME)"|bc) + +SRC_DIR = srcs/ +INC_DIR = includes/ +OBJ_DIR = objs/ + +SRC_BASE = \ +ft_bzero.s\ +ft_cat.s\ +ft_isalnum.s\ +ft_isalpha.s\ +ft_isascii.s\ +ft_isdigit.s\ +ft_islower.s\ +ft_isprint.s\ +ft_isupper.s\ +ft_max.s\ +ft_memcpy.s\ +ft_memset.s\ +ft_min.s\ +ft_putchar.s\ +ft_puts.s\ +ft_strcat.s\ +ft_strdup.s\ +ft_strlen.s\ +ft_tolower.s\ +ft_toupper.s + +SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) +OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.s=.o)) +NB = $(words $(SRC_BASE)) +INDEX = 0 + +all : + @$(MAKE) -j $(NAME) + +$(NAME) : $(OBJ_DIR) $(OBJS) + @ar rcs $(NAME) $(OBJS) + @printf "\r\033[38;5;117m✓ MAKE $(NAME)\033[0m\033[K\n" + +$(OBJ_DIR) : + @mkdir -p $(OBJ_DIR) + @mkdir -p $(dir $(OBJS)) + +$(OBJ_DIR)%.o : $(SRC_DIR)%.s | $(OBJ_DIR) + @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) + @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) + @$(eval TO_DO=$(shell echo $$((20-$(INDEX)*20/$(NB) - 1)))) + @$(eval COLOR=$(shell list=(160 196 202 208 215 221 226 227 190 154 118 82 46); index=$$(($(PERCENT) * $${#list[@]} / 100)); echo "$${list[$$index]}")) + @printf "\r\033[38;5;%dm⌛ [%s]: %2d%% `printf '█%.0s' {0..$(DONE)}`%*s❙%*.*s\033[0m\033[K" $(COLOR) $(NAME) $(PERCENT) $(TO_DO) "" $(DELTA) $(DELTA) "$(shell echo "$@" | sed 's/^.*\///')" + @$(NASM) $(FLAGS_ASM) $< -o $@ + @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) + +clean : + @if [ -e $(OBJ_DIR) ]; \ + then \ + rm -rf $(OBJ_DIR); \ + printf "\r\033[38;5;202m✗ clean $(NAME).\033[0m\033[K\n"; \ + fi; + +fclean : clean + @if [ -e $(NAME) ]; \ + then \ + rm -rf $(NAME); \ + printf "\r\033[38;5;196m✗ fclean $(NAME).\033[0m\033[K\n"; \ + fi; + +re : fclean all + + +test: $(NAME) main.c + gcc -Wall -Wextra -Werror $? -o test + @printf "\r\033[38;5;117m✓ MAKE test\033[0m\033[K\n" + +.PHONY : fclean clean re run-gdb + +-include $(OBJS:.o=.d) diff --git a/libftasm/libft.h b/libftasm/libft.h new file mode 100644 index 00000000..d4187f68 --- /dev/null +++ b/libftasm/libft.h @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include + +/* +** PART_1 +*/ +void ft_bzero(void *i, size_t t); +char *ft_strcat(char *c, char *d); +int ft_isalpha(int i); +int ft_isdigit(int i); +int ft_isalnum(int i); +int ft_isascii(int i); +int ft_isprint(int i); +int ft_toupper(int i); +int ft_tolower(int i); +int ft_puts(char *s); + +/* +** PART_2 +*/ +int ft_strlen(char *s); +void *ft_memset(void *b, int c, size_t len); +void *ft_memcpy(void *dest, const void *src, size_t n); +char *ft_strdup(const char *s1); + +/* +** PART_3 +*/ +void ft_cat(int fd); + +/* +** PART_BONUS +*/ +int ft_isupper(int i); +int ft_islower(int i); +int ft_putchar(int i); +int ft_min(int a, int b); +int ft_max(int a, int b); diff --git a/libftasm/main.c b/libftasm/main.c new file mode 100644 index 00000000..4bc8b771 --- /dev/null +++ b/libftasm/main.c @@ -0,0 +1,669 @@ +#include "libft.h" +#include +#include + +int ft_putstr(const char *str) +{ + return (write(1, str, strlen(str))); +} + +int ft_putnstr(const char *str, size_t n) +{ + return (write(1, str, n)); +} + +int test_bzero() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char str[] = "Bonjour je suis une chaine de char!\n"; + char str_cmp[] = "Bonjour je suis une chaine de char!\n"; + int len = strlen(str); + int result = 0; + int i; + + ft_bzero(NULL, 250); + + bzero(str_cmp, 1); + ft_bzero(str, 1); + i = -1; + ++result; + while (++i < len) + { + if (str[i] != str_cmp[i]) + { + printf("Failed[%d]: %c vs %c at pos: %d\n", result, str[i], str_cmp[i], i); + ft_putnstr(str, len); + ft_putnstr(str_cmp, len); + return(1); + } + } + bzero(str_cmp + 5, 4); + ft_bzero(str + 5, 4); + ++result; + i = -1; + while (++i < len) + { + if (str[i] != str_cmp[i]) + { + printf("Failed[%d]: %c vs %c at pos: %d\n", result, str[i], str_cmp[i], i); + ft_putnstr(str, len); + ft_putnstr(str_cmp, len); + return(1); + } + } + bzero(str_cmp + 2, len - 3); + ft_bzero(str + 2, len - 3); + ++result; + i = -1; + while (++i < len) + { + if (str[i] != str_cmp[i]) + { + printf("Failed[%d]: %c vs %c at pos: %d\n", result, str[i], str_cmp[i], i); + ft_putnstr(str, len); + ft_putnstr(str_cmp, len); + return(1); + } + } + return (0); +} + +int test_strcat() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char str[20] = "first_"; + char str2[] = "second\n"; + char str_cmp[20] = "first_"; + char str_cmp2[] = "second\n"; + int len = 20; + int i; + + strcat(str_cmp, str_cmp2); + ft_strcat(str, str2); + i = -1; + while (++i < len) + { + if (str[i] != str_cmp[i]) + { + printf("Failed: %c vs %c at pos: %d\n", str[i], str_cmp[i], i); + ft_putnstr(str, len); + ft_putnstr(str_cmp, len); + return(1); + } + } + return (0); +} + +int test_isalpha() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_isalpha(a) == 0) != (ret_cmp = isalpha(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return (1); + } + } + return (0); +} + +int test_isdigit() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_isdigit(a) == 0) != (ret_cmp = isdigit(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + return (0); +} + +int test_isascii() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_isascii(a) == 0) != (ret_cmp = isascii(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + return (0); +} + +int test_isalnum() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_isalnum(a) == 0) != (ret_cmp = isalnum(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + return (0); +} + +int test_isprint() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_isprint(a) == 0) != (ret_cmp = isprint(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + return (0); +} + +int test_toupper() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + while (++a < 127) + { + if (ft_toupper(a) != toupper(a)) + { + printf("FAILED: %c [%d]\n", a, a); + return(1); + } + } + return (0); +} + +int test_tolower() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + while (++a < 127) + { + if (ft_tolower(a) != tolower(a)) + { + printf("FAILED: %c [%d]\n", a, a); + return(1); + } + } + return (0); +} + +int test_puts() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char str[] = "It's a char line you have to print. Not this one"; + str[35] = 0; + int ret, ret_cmp; + printf("Original:|"); ret = puts("");printf("|\n"); + printf("Notre :|"); ret_cmp = ft_puts("");printf("|\n"); +#ifdef __APPLE__ + if (ret != ret_cmp) + { + printf("FAILED: %d should be %d\n", ret_cmp, ret); + return (1); + } +#endif +#ifdef __APPLE__ +// puts(NULL) segfaults on linux because the compiler lets you shoot yourself + printf("Original:|"); ret = puts(NULL);printf("|\n"); + printf("Notre :|"); ret_cmp = ft_puts(NULL);printf("|\n"); + if (ret != ret_cmp) + { + printf("FAILED: %d should be %d\n", ret_cmp, ret); + return (1); + } +#endif + printf("Notre :|"); ret = ft_puts(str);printf("|\n"); + printf("Original:|"); ret_cmp = puts(str);printf("|\n"); +#ifdef __APPLE__ + if (ret != ret_cmp) + { + printf("FAILED: %d should be %d\n", ret_cmp, ret); + return (1); + } +#endif + return (0); +} + +int test_strlen() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char str[] = "zagaga"; + int ret, ret_cmp; + ret = ft_strlen(str); + ret_cmp = strlen(str); + if (ret != ret_cmp) + { + printf("FAILED: %d vs %d (on %s)", ret, ret_cmp, str); + return (1); + } + ret = ft_strlen(NULL); + ret_cmp = 0; + if (ret != ret_cmp) + { + printf("FAILED: %d vs %d (on nullptr)", ret, ret_cmp); + return (1); + } + return (0); +} + +int test_memset() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + char str[] = "Bonjour je suis une chaine de char!\n"; + char str_cmp[] = "Bonjour je suis une chaine de char!\n"; + char *ret, *ret_cmp; + int len = strlen(str); + int result = 0; + int i; + + while (++a < 127) + { + ++result; + if (ft_memset(NULL, a, 250) != NULL) + { + printf("Failed[%d]: memset on NULL\n", result); + return (1); + } + ret_cmp = memset(str_cmp, a, 1); + ret = ft_memset(str, a, 1); + i = -1; + ++result; + while (++i < len) + { + if (ret[i] != ret_cmp[i]) + { + ft_putnstr(ret, len); + ft_putnstr(ret_cmp, len); + printf("Failed[%d]: %c vs %c at pos: %d/%d\n", result, ret[i], ret_cmp[i], i, len); + return(1); + } + } + ret_cmp = memset(str_cmp + 5, a, 4); + ret = ft_memset(str + 5, a, 4); + ++result; + i = -1; + while (++i < (len - 5)) + { + if (ret[i] != ret_cmp[i]) + { + ft_putnstr(ret, len); + ft_putnstr(ret_cmp, len); + printf("Failed[%d]: %c vs %c at pos: %d/%d\n", result, ret[i], ret_cmp[i], i, len); + return(1); + } + } + ret_cmp = memset(str_cmp + 2, a, len - 3); + ret = ft_memset(str + 2, a, len - 3); + ++result; + i = -1; + while (++i < (len - 2)) + { + if (ret[i] != ret_cmp[i]) + { + ft_putnstr(ret, len); + ft_putnstr(ret_cmp, len); + printf("Failed[%d]: %c vs %c at pos: %d/%d\n", result, ret[i], ret_cmp[i], i, len); + return(1); + } + } + } + return (0); +} + +int test_memcpy() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char str[] = "Bonjour je suis une chaine de char!\n"; + char str_cmp[] = "Bonjour je suis une chaine de char!\n"; + char ret[100], ret_cmp[100]; + char *me, *cmp; + int len = strlen(str); + int result = 0; + int i; + + ++result; + if (ft_memcpy(NULL, str, 250) != NULL) + { + printf("Failed[%d]: memcpy on dst=NULL\n", result); + return (1); + } + ++result; + if (ft_memcpy(ret, NULL, 250) != ret) + { + printf("Failed[%d]: memcpy on src=NULL\n", result); + return (1); + } + cmp = memcpy(ret_cmp, str_cmp, len); + me = ft_memcpy(ret, str, len); + i = -1; + ++result; + while (++i < len) + { + if (me[i] != cmp[i]) + { + ft_putnstr(ret, len); + ft_putnstr(ret_cmp, len); + printf("Failed[%d]: %c vs %c at pos: %d/%d\n", result, me[i], cmp[i], i, len); + return(1); + } + } + memcpy(ret_cmp + len, str_cmp, len); + ft_memcpy(ret + len, str, len); + i = -1; + ++result; + while (++i < 2 * len) + { + if (me[i] != cmp[i]) + { + ft_putnstr(ret, 2 * len); + ft_putnstr(ret_cmp, 2 * len); + printf("Failed[%d]: %c vs %c at pos: %d/%d\n", result, me[i], cmp[i], i, 2 * len); + return(1); + } + } + return (0); +} + +int test_strdup() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char *str; + char *str_cmp; + int len, len_cmp; + int i; + if ((str = ft_strdup(NULL)) != NULL) + { + printf("FAILED: not support NULL\n"); + return (1); + } + str = ft_strdup("Coucou"); + str_cmp = strdup("Coucou"); + len = strlen(str); + len_cmp = strlen(str_cmp); + if (len != len_cmp) + { + printf("FAILED: len is %d vs %d\n", len, len_cmp); + return (1); + } + i = -1; + while (++i < len) + { + if (str[i] != str_cmp[i]) + { + ft_putnstr(str, len); + ft_putnstr(str_cmp, len); + printf("FAILED: %c vs %c\n", str[i], str_cmp[i]); + return (1); + } + } + free(str); + free(str_cmp); + + return (0); +} + +int test_cat(char **av) +{ + ft_putstr(__func__); ft_putstr(":\n"); + + (void)av; + ft_cat(0); + ft_cat(open(__FILE__, O_RDONLY)); + ft_cat(open(av[0], O_RDONLY)); + ft_cat(-42); + return (0); +} + +int test_isupper() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_isupper(a) == 0) != (ret_cmp = isupper(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + return (0); +} + +int test_islower() +{ + ft_putstr(__func__); ft_putstr(":\n"); + char a = -1; + int ret, ret_cmp; + while (++a < 127) + { + if ((ret = ft_islower(a) == 0) != (ret_cmp = islower(a) == 0)) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + return (0); +} + +int test_putchar() +{ + ft_putstr(__func__); ft_putstr(":\n"); + int a = -500; + int ret, ret_cmp; + while (++a < 500) + { + if ((ret = ft_putchar(a)) != (ret_cmp = putchar(a))) + { + printf("FAILED: %c [%d] => %d vs %d\n", a, a, ret, ret_cmp); + return(1); + } + } + ft_putstr(":\n"); + return (0); +} + +int test_max() +{ + ft_putstr(__func__); ft_putstr(":\n"); + unsigned int a, b, ret, ret_cmp; + int ans = 0; + a = 5; + b = 6; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = 6; + b = 5; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -10; + b = -12; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -12; + b = -10; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -10; + b = 12; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -12; + b = 10; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = 0; + b = 10; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -12; + b = 0; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -2147483648; + b = 2147483647; + if ((ret = ft_max(a,b)) != (ret_cmp = fmax(a,b))) + { + dprintf(2, "FAILED max(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + + return (ans); +} + +int test_min() +{ + ft_putstr(__func__); ft_putstr(":\n"); + unsigned int a, b, ret, ret_cmp; + int ans = 0; + a = 5; + b = 6; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = 6; + b = 5; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -10; + b = -12; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -12; + b = -10; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -10; + b = 12; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -12; + b = 10; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = 0; + b = 10; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -12; + b = 0; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + a = -2147483648; + b = 2147483647; + if ((ret = ft_min(a,b)) != (ret_cmp = fmin(a,b))) + { + dprintf(2, "FAILED min(%d, %d) => %d vs %d\n",a,b,ret,ret_cmp); + ++ans; + } + + return (ans); +} + + +int main(int argc, char **argv) +{ + (void)argc; + setbuf(stdout, NULL); + ft_putstr("\nPART 1:\n_______\n"); + if ( + test_bzero() || + test_strcat() || + test_isalpha() || + test_isdigit() || + test_isalnum() || + test_isascii() || + test_isprint() || + test_toupper() || + test_tolower() || + test_puts() + ) + return (1); + ft_putstr("PART 2:\n_______\n"); + if ( + test_strlen() || + test_memset() || + test_memcpy() || + test_strdup() + ) + return (1); + ft_putstr("\nPART 3:\n_______\n"); + if (test_cat(argv)) + return (1); + ft_putstr("\nPART BONUS:\n_______\n"); + if ( + test_isupper() || + test_islower() || + test_putchar() || + test_min() || + test_max() + ) + return (1); + puts("\033c\n\033[38;5;117mALL PASSED\n___________\n\033[0m"); + return (0); +} diff --git a/libftasm/srcs/ft_bzero.s b/libftasm/srcs/ft_bzero.s new file mode 100644 index 00000000..1351d09b --- /dev/null +++ b/libftasm/srcs/ft_bzero.s @@ -0,0 +1,19 @@ +global _ft_bzero +global ft_bzero +section .text + +_ft_bzero: +ft_bzero: + cmp rdi, 0 + je end + cmp rsi, 0 + je end +start_loop: + mov BYTE [rdi], 0 + inc rdi + dec rsi + jnz start_loop +; loop start_loop + +end: + ret diff --git a/libftasm/srcs/ft_cat.s b/libftasm/srcs/ft_cat.s new file mode 100644 index 00000000..c145c0d2 --- /dev/null +++ b/libftasm/srcs/ft_cat.s @@ -0,0 +1,36 @@ +global _ft_cat +global ft_cat + +%define STDOUT 1 +%define BUFF_SIZE 1024 + +section .bss + buf: resb BUFF_SIZE + +section .text +; void ft_cat(int fd) +_ft_cat: +ft_cat: + mov r8, rdi + cmp rdi, 0 + jl end + lea rsi, [rel buf] + mov rdx, BUFF_SIZE + mov rax, READ ; int read(int fd, void *buf, size_t count) + syscall + jc end + cmp rax, 0 + jle end + + mov rdi, STDOUT + mov rdx, rax + mov rax, WRITE ; int write(int fd, const void *buf, size_t count) + syscall + jc end + cmp rax, 0 + jl end + + mov rdi, r8 + jmp ft_cat +end: + ret diff --git a/libftasm/srcs/ft_isalnum.s b/libftasm/srcs/ft_isalnum.s new file mode 100644 index 00000000..0476505a --- /dev/null +++ b/libftasm/srcs/ft_isalnum.s @@ -0,0 +1,14 @@ +global _ft_isalnum +global ft_isalnum + +extern ft_isalpha +extern ft_isdigit + +_ft_isalnum: +ft_isalnum: + mov rax, 0 + call ft_isalpha + cmp rax, 0 + jne end + call ft_isdigit +end: ret diff --git a/libftasm/srcs/ft_isalpha.s b/libftasm/srcs/ft_isalpha.s new file mode 100644 index 00000000..bd091f00 --- /dev/null +++ b/libftasm/srcs/ft_isalpha.s @@ -0,0 +1,15 @@ +global _ft_isalpha +global ft_isalpha + +extern ft_islower +extern ft_isupper + +_ft_isalpha: +ft_isalpha: + mov rax, 0 + call ft_isupper + cmp rax, 0 + jne end + call ft_islower + +end: ret diff --git a/libftasm/srcs/ft_isascii.s b/libftasm/srcs/ft_isascii.s new file mode 100644 index 00000000..75901217 --- /dev/null +++ b/libftasm/srcs/ft_isascii.s @@ -0,0 +1,11 @@ +global _ft_isascii +global ft_isascii + +_ft_isascii: +ft_isascii: + mov rax, 0 + and rdi, 128 + jne end + mov rax, 1 +end: + ret diff --git a/libftasm/srcs/ft_isdigit.s b/libftasm/srcs/ft_isdigit.s new file mode 100644 index 00000000..9108750e --- /dev/null +++ b/libftasm/srcs/ft_isdigit.s @@ -0,0 +1,13 @@ +global _ft_isdigit +global ft_isdigit + +_ft_isdigit: +ft_isdigit: + mov rax, 0 + cmp rdi, '0' + jl end + cmp rdi, '9' + jg end + mov rax, rdi +end: + ret diff --git a/libftasm/srcs/ft_islower.s b/libftasm/srcs/ft_islower.s new file mode 100644 index 00000000..231e2e07 --- /dev/null +++ b/libftasm/srcs/ft_islower.s @@ -0,0 +1,12 @@ +global _ft_islower +global ft_islower + +_ft_islower: +ft_islower: + mov rax, 0 + cmp rdi, 'a' + jl end + cmp rdi, 'z' + jg end + mov rax, rdi +end: ret diff --git a/libftasm/srcs/ft_isprint.s b/libftasm/srcs/ft_isprint.s new file mode 100644 index 00000000..7655346d --- /dev/null +++ b/libftasm/srcs/ft_isprint.s @@ -0,0 +1,13 @@ +global _ft_isprint +global ft_isprint + +_ft_isprint: +ft_isprint: + mov rax, 0 + cmp rdi, ' ' + jl end + cmp rdi, '~' + jg end + mov rax, rdi +end: + ret diff --git a/libftasm/srcs/ft_isupper.s b/libftasm/srcs/ft_isupper.s new file mode 100644 index 00000000..74dc3401 --- /dev/null +++ b/libftasm/srcs/ft_isupper.s @@ -0,0 +1,12 @@ +global _ft_isupper +global ft_isupper + +_ft_isupper: +ft_isupper: + mov rax, 0 + cmp rdi, 'A' + jl end + cmp rdi, 'Z' + jg end + mov rax, rdi +end: ret diff --git a/libftasm/srcs/ft_max.s b/libftasm/srcs/ft_max.s new file mode 100644 index 00000000..83f97bce --- /dev/null +++ b/libftasm/srcs/ft_max.s @@ -0,0 +1,13 @@ +global _ft_max +global ft_max + +section .text +; int ft_max(int a, int b) +_ft_max: +ft_max: + mov rax, rdi + cmp rdi, rsi + jge end + mov rax, rsi +end: + ret diff --git a/libftasm/srcs/ft_memcpy.s b/libftasm/srcs/ft_memcpy.s new file mode 100644 index 00000000..4af29ac5 --- /dev/null +++ b/libftasm/srcs/ft_memcpy.s @@ -0,0 +1,19 @@ +global _ft_memcpy +global ft_memcpy + +; void *ft_memcpy(void *dst, const void *src, size_t n) +_ft_memcpy: +ft_memcpy: + push rdi + cmp rdi, 0 + je end + cmp rsi, 0 + je end + mov rcx, rdx + cld + rep movsb + +end: + pop rdi + mov rax, rdi + ret diff --git a/libftasm/srcs/ft_memset.s b/libftasm/srcs/ft_memset.s new file mode 100644 index 00000000..d5f484f2 --- /dev/null +++ b/libftasm/srcs/ft_memset.s @@ -0,0 +1,17 @@ +global _ft_memset +global ft_memset + +_ft_memset: ; void *ft_memset(void *s, int c, size_t n) +ft_memset: + push rdi + cmp rdi, 0 + je end + mov rcx, rdx + mov al, sil + cld + rep stosb + +end: + pop rdi + mov rax, rdi + ret diff --git a/libftasm/srcs/ft_min.s b/libftasm/srcs/ft_min.s new file mode 100644 index 00000000..016eb665 --- /dev/null +++ b/libftasm/srcs/ft_min.s @@ -0,0 +1,13 @@ +global _ft_min +global ft_min + +section .text +; int ft_min(int a, int b) +_ft_min: +ft_min: + mov rax, rdi + cmp rdi, rsi + jl end + mov rax, rsi +end: + ret diff --git a/libftasm/srcs/ft_putchar.s b/libftasm/srcs/ft_putchar.s new file mode 100644 index 00000000..e29d6655 --- /dev/null +++ b/libftasm/srcs/ft_putchar.s @@ -0,0 +1,37 @@ +%define STDOUT 1 + +global _ft_putchar +global ft_putchar + +section .data + string: db "A" + +section .text + +; int ft_putchar(int c) +_ft_putchar: +ft_putchar: + ; save c value + push rdi + + ; int write(int fd, char *str, size_t len) + lea rsi, [rel string] ; char *str + mov [rsi], dil + mov rdx, 1 ; size_t len + mov rdi, STDOUT ; int fd + mov rax, WRITE + syscall + + cmp rax, 0 + jl err + + ; success case then return c + pop rax + movzx rax, al ; cast to char + ret + +err: + ; error case then return -1 + pop rax + mov rax, -1 + ret diff --git a/libftasm/srcs/ft_puts.s b/libftasm/srcs/ft_puts.s new file mode 100644 index 00000000..78260fe5 --- /dev/null +++ b/libftasm/srcs/ft_puts.s @@ -0,0 +1,42 @@ +global _ft_puts +global ft_puts + +extern _ft_strlen +extern _ft_putchar + +%define STDOUT 1 + +section .data + string: db "(null)" + .len: equ $ - string + +section .text +_ft_puts: ; int puts(const char *s) +ft_puts: + push rdi ; because strlen will clobber rdi + call _ft_strlen + pop rdi + cmp rax, 0 + je print_nl ; if empty string skip printing + +print_string: + ; int write(int fd, const char *str, size_t size) + mov rsi, rdi ; char *str + mov rdi, STDOUT ; int fd + mov rdx, rax ; size_t strlen + mov rax, WRITE ; WRITE + syscall + cmp rax, 0 + jl finish + +print_nl: + mov rdi, 0xa + call _ft_putchar + cmp rax, 0 + ret + jl finish + +success: + mov rax, 0xa ; success returns '\n' +finish: + ret diff --git a/libftasm/srcs/ft_strcat.s b/libftasm/srcs/ft_strcat.s new file mode 100644 index 00000000..603d49d0 --- /dev/null +++ b/libftasm/srcs/ft_strcat.s @@ -0,0 +1,21 @@ +global _ft_strcat +global ft_strcat + +_ft_strcat: +ft_strcat: + mov rax, rdi +rloop: + cmp byte [rdi], 0 + je wloop + inc rdi + jmp rloop + +wloop: + mov cl, [rsi] + mov [rdi], cl + cmp byte [rdi], 0 + je end + inc rdi + inc rsi + jmp wloop +end: ret diff --git a/libftasm/srcs/ft_strdup.s b/libftasm/srcs/ft_strdup.s new file mode 100644 index 00000000..de78e1fa --- /dev/null +++ b/libftasm/srcs/ft_strdup.s @@ -0,0 +1,35 @@ +global _ft_strdup +global ft_strdup + +extern _malloc +extern malloc +extern _ft_strlen +extern _ft_memcpy + +; void *ft_strdup(const char *d) +_ft_strdup: +ft_strdup: + mov rax, 0 + cmp rdi, 0 + je end + + push rdi + call _ft_strlen + inc rax + push rax + mov rdi, rax + + sub rsp, 8 ; align stack to 16 bytes, x86_64 or mach don't know + call _malloc + add rsp, 8 + + pop rcx + pop rsi + cmp rax, 0 + je end + + mov rdi, rax + cld ; clear the directon flag + rep movsb +end: + ret diff --git a/libftasm/srcs/ft_strlen.s b/libftasm/srcs/ft_strlen.s new file mode 100644 index 00000000..0d640ca2 --- /dev/null +++ b/libftasm/srcs/ft_strlen.s @@ -0,0 +1,18 @@ +global _ft_strlen +global ft_strlen + +_ft_strlen: +ft_strlen: + mov rax, 0 + cmp rdi, 0 + je end + + mov rcx, -1 + cld + repnz scasb + + not rcx + lea rax, [rcx - 1] + +end: + ret diff --git a/libftasm/srcs/ft_tolower.s b/libftasm/srcs/ft_tolower.s new file mode 100644 index 00000000..d2f66dc2 --- /dev/null +++ b/libftasm/srcs/ft_tolower.s @@ -0,0 +1,13 @@ +global _ft_tolower +global ft_tolower + +_ft_tolower: +ft_tolower: + mov rax, rdi + cmp rdi, 'A' + jl end + cmp rdi, 'Z' + jg end + add rax, 32 +end: + ret diff --git a/libftasm/srcs/ft_toupper.s b/libftasm/srcs/ft_toupper.s new file mode 100644 index 00000000..8079cde1 --- /dev/null +++ b/libftasm/srcs/ft_toupper.s @@ -0,0 +1,13 @@ +global _ft_toupper +global ft_toupper + +_ft_toupper: +ft_toupper: + mov rax, rdi + cmp rdi, 'a' + jl end + cmp rdi, 'z' + jg end + sub rax, 32 +end: + ret