Merge libftasm with full history

This commit is contained in:
Jack 2026-01-29 18:05:21 -03:00
commit 274f4a2719
No known key found for this signature in database
24 changed files with 1210 additions and 0 deletions

2
libftasm/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
test
libfts.a

110
libftasm/Makefile Normal file
View file

@ -0,0 +1,110 @@
#* ************************************************************************** *#
#* *#
#* ::: :::::::: *#
#* Makefile :+: :+: :+: *#
#* +:+ +:+ +:+ *#
#* By: wescande <wescande@student.42.fr> +#+ +:+ +#+ *#
#* +#+#+#+#+#+ +#+ *#
#* 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)

43
libftasm/libft.h Normal file
View file

@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
** 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);

669
libftasm/main.c Normal file
View file

@ -0,0 +1,669 @@
#include "libft.h"
#include <ctype.h>
#include <math.h>
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);
}

19
libftasm/srcs/ft_bzero.s Normal file
View file

@ -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

36
libftasm/srcs/ft_cat.s Normal file
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

13
libftasm/srcs/ft_max.s Normal file
View file

@ -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

19
libftasm/srcs/ft_memcpy.s Normal file
View file

@ -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

17
libftasm/srcs/ft_memset.s Normal file
View file

@ -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

13
libftasm/srcs/ft_min.s Normal file
View file

@ -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

View file

@ -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

42
libftasm/srcs/ft_puts.s Normal file
View file

@ -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

21
libftasm/srcs/ft_strcat.s Normal file
View file

@ -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

35
libftasm/srcs/ft_strdup.s Normal file
View file

@ -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

18
libftasm/srcs/ft_strlen.s Normal file
View file

@ -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

View file

@ -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

View file

@ -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