From 9af248e8a78f111a39d507f199d56eb8af6e52d6 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 25 Nov 2019 03:37:45 +0100 Subject: ft_atoi_base.s kinda done --- ft_atoi_base.s | 279 +++++++++++++++++++++++++++++++++------------------ ft_list_push_front.s | 32 +++--- ft_list_size.s | 40 ++++---- ft_strcmp.s | 42 ++++---- ft_strcpy.s | 22 ++-- ft_strdup.s | 13 ++- ft_strlen.s | 8 +- main.c | 11 +- 8 files changed, 270 insertions(+), 177 deletions(-) diff --git a/ft_atoi_base.s b/ft_atoi_base.s index 581b68b..663b399 100644 --- a/ft_atoi_base.s +++ b/ft_atoi_base.s @@ -10,126 +10,213 @@ ; ; ; **************************************************************************** ; + +; Only need to save reg if we use them after + +; caller rules: +; 1. save caller-saved reg r10, r11 +; /!\ all param reg +; 2. pass param with regs rdi, rsi, rdx, rcx, r8, r9 +; if there is more pass them onto the stack in reverse order +; 3. use call +; 4. restore stack state by removing passed on the stack param +; 5. return value of callee in rax +; 6. restore the caller-saved register and saved passed params +; We can assume that no other register has been altered. + + +; callee rules: +; 1. allocate local variables by sub sum of sizes of thoses var to rsp +; the stack grows downward so we will access those local by adding to rsp. +; 2. push callee-saved reg onto the stack: rbx, rbp, r12, r13, r14, r15. +; +; >>> function body <<< +; +; 3. place return value in rax +; 4. restore callee-saved registers +; 5. remove local var, add to the stack the previoulsy subtracted amount. +; 6. use ret + + extern _ft_strlen global _ft_atoi_base ; int ft_atoi_base(const char *str, const char *base); _ft_atoi_base: - mov r12, rdi ; r12 = str - mov r13, rsi ; r13 = base - + ; ===prolog=== + ; long int nb (8) + ; int radix (4) + ; int is_negative (4) + sub rsp, 16 + mov qword [rsp], 0x0 ; nb = 0 + mov dword [rsp + 8], 0x0 ; radix = 0 + mov dword [rsp + 12], 0x0 ; is_negative = 0 + push rbx + push r11 + push r15 + + ; ===body=== ; check if the base is valid - mov rdi, r13 + push rdi + mov rdi, rsi call _check_base - cmp rax, 0 - je CHECK_BASE_FALSE - + pop rdi + cmp eax, 0x0 + je FT_ATOI_BASE_ERROR ; ignore space in front - mov r15, -1 ; str index - FT_ATOI_BASE_IGNORE_SPACES: - inc r15 - mov dil, byte [r12 + r15] - call _ft_isspace - cmp rax, 1 - je FT_ATOI_BASE_IGNORE_SPACES - - - ; cmp byte [r12 + r15], 0x2d - ; mov r11, zf ; r11 = is negative - - mov rdi, r13 + mov rbx, -1 ; rbx is rdi str index +FT_ATOI_BASE_IGNORE_SPACES: + inc rbx + push rdi + mov dil, byte [rdi + rbx] + call _ft_isspace + pop rdi + cmp rax, 1 + je FT_ATOI_BASE_IGNORE_SPACES + + ; ignore '+', '-' reverse the current sign + mov qword [rsp], 0x0 ; nb = 0 + mov dword [rsp + 8], 0x0 ; radix = 0 + mov dword [rsp + 12], 0x0 ; is_negative = 0 + mov dword [rsp + 12], 0x0 ; weird behavior FIXME + dec rbx + jmp FT_ATOI_BASE_SIGN_LOOP +FT_ATOI_BASE_SIGN_LOOP_FOUND_NEG: + not dword [rsp + 12] +FT_ATOI_BASE_SIGN_LOOP: + inc rbx + cmp byte [rdi + rbx], 0x2b ; if '+' + je FT_ATOI_BASE_SIGN_LOOP + cmp byte [rdi + rbx], 0x2d ; if '-' + je FT_ATOI_BASE_SIGN_LOOP_FOUND_NEG + + ; base radix + push rdi + mov rdi, rsi call _ft_strlen - mov r14, rax ; r14 = radix - - xor rcx, rcx ; return value - FT_ATOI_BASE_LOOP: - mov sil, [r12 + r15] - call _base_pos ; get value of the current char int the base - cmp rax, -1 ; if is not in base break - je FT_ATOI_BASE_LOOP_END - - imul rcx, r14 ; multiply by the radix - add rcx, rax ; add the current value - inc r15 - jmp FT_ATOI_BASE_LOOP - FT_ATOI_BASE_LOOP_END: - mov rax, rcx - ret + pop rdi + mov dword [rsp + 8], eax + ; main loop +FT_ATOI_BASE_LOOP: + push rdi + push rsi + mov dil, byte [rdi + rbx] + call _base_pos ; get value of the current char int the base + pop rsi + pop rdi + cmp rax, -1 ; if is not in base break + je FT_ATOI_BASE_LOOP_END + + mov r11, [rsp] ; place nb in register for multiplication + xor r15, r15 ; same for radix + mov r15d, dword [rsp + 8] + imul r11, r15 ; multiply by the radix + mov [rsp], r11 ; store multiplication result + add [rsp], rax ; add the current value + + inc rbx + jmp FT_ATOI_BASE_LOOP +FT_ATOI_BASE_LOOP_END: + + cmp dword [rsp + 12], 0 + je FT_ATOI_BASE_END + neg qword [rsp] + + ; ===epilog=== +FT_ATOI_BASE_END: + mov rax, [rsp] + pop r15 + pop r11 + pop rbx + add rsp, 16 + ret +FT_ATOI_BASE_ERROR: + mov rax, 0x0 + pop r15 + pop r11 + pop rbx + add rsp, 16 + ret -; rdi: char *base -; sil: char searched +; dil: char searched +; rsi: char *base _base_pos: - mov rax, -1 - BASE_POS_LOOP: - inc rax - cmp byte [rdi + rax], 0 ; if '\0' char not in base - je BASE_POS_NOT_FOUND - cmp sil, byte [rdi + rax] ; loop until '\0' or found - jne BASE_POS_LOOP + mov rax, -1 +BASE_POS_LOOP: + inc rax + cmp byte [rsi + rax], 0 ; if '\0' char not in base + je BASE_POS_NOT_FOUND + cmp dil, byte [rsi + rax] ; loop until '\0' or found + jne BASE_POS_LOOP + ret +BASE_POS_NOT_FOUND: + mov rax, -1 ret - BASE_POS_NOT_FOUND: - mov rax, -1 - ret ; rdi: char *base _check_base: - ; check for empty or size 1 base + sub rsp, 4 + mov dword [rsp], 0 +; check for empty or size 1 base push rdi call _ft_strlen - pop rdi - cmp rax, 2 - jl CHECK_BASE_FALSE - - xor rcx, rcx ; rcx = index - CHECK_BASE_LOOP: - cmp byte [rdi + rcx], 0 - je CHECK_BASE_LOOP_END - cmp byte [rdi + rcx], 0x2b ; check '+' - je CHECK_BASE_FALSE - cmp byte [rdi + rcx], 0x2d ; check '-' - je CHECK_BASE_FALSE - - push rdi ; save base - mov dil, [rdi + rcx] ; pass current char as argument - call _ft_isspace - pop rdi ; recover base - cmp rax, 1 - je CHECK_BASE_FALSE ; check for spaces - - ; check for duplicates in base - mov rdx, rcx ; index from curr +1 - CHECK_BASE_DUP_LOOP: - inc rdx - mov r10b, byte [rdi + rcx] ; r10b = checked char - cmp r10b, byte [rdi + rdx] ; check if found dup - je CHECK_BASE_FALSE - cmp byte [rdi + rdx], 0 ; if \0 end dup check - jne CHECK_BASE_DUP_LOOP - - inc rcx - jmp CHECK_BASE_LOOP - CHECK_BASE_LOOP_END: - - mov rax, 1 + pop rdi + cmp rax, 2 + jl CHECK_BASE_FALSE + + ; xor rcx, rcx +CHECK_BASE_LOOP: + cmp byte [rdi], 0 + je CHECK_BASE_LOOP_END + cmp byte [rdi], 0x2b ; check '+' + je CHECK_BASE_FALSE + cmp byte [rdi], 0x2d ; check '-' + je CHECK_BASE_FALSE + +; check for spaces + push rdi + mov dil, [rdi] ; pass current char as argument + call _ft_isspace + pop rdi + cmp rax, 1 + je CHECK_BASE_FALSE + +; check for duplicates in base + xor rcx, rcx ; index from curr +1 +CHECK_BASE_DUP_LOOP: + inc rcx + mov r10b, byte [rdi] ; r10b = checked char + cmp r10b, byte [rdi + rcx] ; check if found dup + je CHECK_BASE_FALSE + cmp byte [rdi + rcx], 0 ; if \0 end dup check + jne CHECK_BASE_DUP_LOOP + + inc rdi + jmp CHECK_BASE_LOOP +CHECK_BASE_LOOP_END: + + add rsp, 4 + mov rax, 1 + ret +CHECK_BASE_FALSE: + add rsp, 4 + xor rax, rax ret - CHECK_BASE_FALSE: - xor rax, rax - ret ; dil: char c _ft_isspace: - cmp dil, 20h ; if space jump next - je ISSPACE_TRUE_END - sub dil, 9h - cmp dil, 5h - jl ISSPACE_TRUE_END - xor rax, rax + cmp dil, 0x20 + je ISSPACE_TRUE + sub dil, 0x9 + cmp dil, 0x5 + jl ISSPACE_TRUE + xor rax, rax + ret +ISSPACE_TRUE: + mov rax, 0x1 ret - ISSPACE_TRUE_END: - mov rax, 1 - ret diff --git a/ft_list_push_front.s b/ft_list_push_front.s index 835aa2c..686ee10 100644 --- a/ft_list_push_front.s +++ b/ft_list_push_front.s @@ -1,22 +1,22 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# ft_list_push_front.s :+: :+: :+: # -# +:+ +:+ +:+ # -# By: cacharle +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2019/11/22 20:55:08 by cacharle #+# #+# # -# Updated: 2019/11/22 21:17:45 by cacharle ### ########.fr # -# # -# **************************************************************************** # +; **************************************************************************** ; +; ; +; ::: :::::::: ; +; ft_list_push_front.s :+: :+: :+: ; +; +:+ +:+ +:+ ; +; By: cacharle +#+ +:+ +#+ ; +; +#+#+#+#+#+ +#+ ; +; Created: 2019/11/22 20:55:08 by cacharle #+# #+# ; +; Updated: 2019/11/22 21:17:45 by cacharle ### ########.fr ; +; ; +; **************************************************************************** ; -.globl _ft_list_push_front +global _ft_list_push_front -# void ft_list_push_front(t_list **begin_list, void *data); +; void ft_list_push_front(t_list **begin_list, void *data); _ft_list_push_front: cmp rdi, 0 - je FT_LIST_PUSH_FRONT_END + je FT_LIST_PUSH_FRONT_END mov [rsi + 8], [rdi] mov [rdi], rsi - FT_LIST_PUSH_FRONT_END: - ret +FT_LIST_PUSH_FRONT_END: + ret diff --git a/ft_list_size.s b/ft_list_size.s index c37de61..ad89999 100644 --- a/ft_list_size.s +++ b/ft_list_size.s @@ -1,25 +1,25 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# ft_list_size.s :+: :+: :+: # -# +:+ +:+ +:+ # -# By: cacharle +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2019/11/22 20:59:52 by cacharle #+# #+# # -# Updated: 2019/11/22 21:17:54 by cacharle ### ########.fr # -# # -# **************************************************************************** # +; **************************************************************************** ; +; ; +; ::: :::::::: ; +; ft_list_size.s :+: :+: :+: ; +; +:+ +:+ +:+ ; +; By: cacharle +#+ +:+ +#+ ; +; +#+#+#+#+#+ +#+ ; +; Created: 2019/11/22 20:59:52 by cacharle #+# #+# ; +; Updated: 2019/11/24 01:55:14 by cacharle ### ########.fr ; +; ; +; **************************************************************************** ; -.globl _ft_list_size +global _ft_list_size -# int ft_list_size(t_list *begin_list); +; int ft_list_size(t_list *begin_list); _ft_list_size: xor eax, eax - FT_LIST_SIZE_LOOP: - cmp rdi, 0 - je FT_LIST_SIZE_END - inc eax - mov rdi, [rdi + 8] - jmp FT_LIST_SIZE_LOOP - FT_LIST_SIZE_END +FT_LIST_SIZE_LOOP: + cmp rdi, 0 + je FT_LIST_SIZE_END + inc eax + mov rdi, [rdi + 8] + jmp FT_LIST_SIZE_LOOP +FT_LIST_SIZE_END ret diff --git a/ft_strcmp.s b/ft_strcmp.s index 5be82a5..7704aa5 100644 --- a/ft_strcmp.s +++ b/ft_strcmp.s @@ -17,28 +17,28 @@ _ft_strcmp: push r12 push r13 push rcx - mov r12, rdi ; s1 - mov r13, rsi ; s2 - mov rcx, -1 ; index - FT_STRCMP_LOOP: - inc rcx - cmp byte [r12 + rcx], 0 ; check and of s1 - je FT_STRCMP_LOOP_END - mov dl, byte [r12 + rcx] - cmp dl, byte [r13 + rcx] ; s1[rcx] == s2[rcx] - je FT_STRCMP_LOOP - FT_STRCMP_LOOP_END: + mov r12, rdi ; s1 + mov r13, rsi ; s2 + mov rcx, -1 ; index +FT_STRCMP_LOOP: + inc rcx + cmp byte [r12 + rcx], 0 ; check and of s1 + je FT_STRCMP_LOOP_END + mov dl, byte [r12 + rcx] + cmp dl, byte [r13 + rcx] ; s1[rcx] == s2[rcx] + je FT_STRCMP_LOOP +FT_STRCMP_LOOP_END: - xor rax, rax - mov al, byte [r12 + rcx] - sub al, byte [r13 + rcx] - jnc FT_STRCMP_END ; jump end if no substraction overflow + xor rax, rax + mov al, byte [r12 + rcx] + sub al, byte [r13 + rcx] + jnc FT_STRCMP_END ; jump end if no substraction overflow - neg al ; negate al to cancel overflow - neg eax ; negate the whole int since the function returns that type + neg al ; negate al to cancel overflow + neg eax ; negate the whole int since the function returns that type - FT_STRCMP_END: - pop rcx - pop r13 - pop r12 +FT_STRCMP_END: + pop rcx + pop r13 + pop r12 ret diff --git a/ft_strcpy.s b/ft_strcpy.s index 5d32f2d..3789283 100644 --- a/ft_strcpy.s +++ b/ft_strcpy.s @@ -16,15 +16,15 @@ global _ft_strcpy _ft_strcpy: push rbx push rcx - mov rax, rdi ; dst - mov rbx, rsi ; src - mov rcx, -1 - FT_STRCPY_LOOP: - inc rcx - mov dl, byte [rbx + rcx] - mov byte [rax + rcx], dl - cmp byte [rbx + rcx], 0 - jne FT_STRCPY_LOOP - pop rcx - pop rbx + mov rax, rdi ; dst + mov rbx, rsi ; src + mov rcx, -1 +FT_STRCPY_LOOP: + inc rcx + mov dl, byte [rbx + rcx] + mov byte [rax + rcx], dl + cmp byte [rbx + rcx], 0 + jne FT_STRCPY_LOOP + pop rcx + pop rbx ret diff --git a/ft_strdup.s b/ft_strdup.s index 8ff46b5..a31f36f 100644 --- a/ft_strdup.s +++ b/ft_strdup.s @@ -21,14 +21,19 @@ _ft_strdup: push rdi ; save rdi because it will be overwrite for malloc call _ft_strlen ; rdi is still == str - inc rax ; len++ for '\0' + inc rax ; len++ for '\0' - mov rdi, rax ; size to malloc + mov rdi, rax ; size to malloc call _malloc + cmp rax, 0 + je FT_STRDUP_ERROR - pop rsi ; original str as src - mov rdi, rax ; allocated as dest + pop rsi ; original str as src + mov rdi, rax ; allocated as dest call _ft_strcpy ret +FT_STRDUP_ERROR: + pop rdi + ret diff --git a/ft_strlen.s b/ft_strlen.s index 41372eb..2f2dd26 100644 --- a/ft_strlen.s +++ b/ft_strlen.s @@ -15,8 +15,8 @@ global _ft_strlen ; int ft_strlen(char *); _ft_strlen: mov eax, -1 - FT_STRLEN_LOOP: - inc eax - cmp byte [rdi + rax], 0 ; compare rbx[rax] and '\0' - jne FT_STRLEN_LOOP +FT_STRLEN_LOOP: + inc eax + cmp byte [rdi + rax], 0 ; compare rbx[rax] and '\0' + jne FT_STRLEN_LOOP ret diff --git a/main.c b/main.c index b89fdc8..333d2a2 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/22 02:02:24 by cacharle #+# #+# */ -/* Updated: 2019/11/23 04:33:27 by cacharle ### ########.fr */ +/* Updated: 2019/11/25 03:29:53 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,7 +27,6 @@ int ft_write(int, const void*, size_t); int ft_read(int, void*, size_t); char *ft_strdup(const char*); int ft_atoi_base(const char*, const char*); -int check_base(const char*); void ft_list_push_front(t_list **begin_list, void *data); int ft_list_size(t_list *begin_list); @@ -62,14 +61,16 @@ int main() /* int ret = ft_read(0, g, 2); */ /* g[ret] = 0; */ /* printf("%s\n", g); */ - /* */ + /* char *h = ft_strdup("bonjour"); */ + /* 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 010\t0101001", "01")); + /* printf("%d\n", ft_atoi_base(" \t\n\r\v\f\r 10\t0101001", "01")); */ + printf("_%d_\n", ft_atoi_base(" 755x+", "01234567")); return 0; } -- cgit