From c0bcb694bbcef0273d6e6fa93854ce6a10432b87 Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 23 Nov 2019 04:43:37 +0100 Subject: ft_atoi_base with calling convention is better, still need to handle negative --- ft_atoi_base.s | 156 +++++++++++++++++++++++++++++++-------------------------- main.c | 10 ++-- 2 files changed, 91 insertions(+), 75 deletions(-) diff --git a/ft_atoi_base.s b/ft_atoi_base.s index e51487c..581b68b 100644 --- a/ft_atoi_base.s +++ b/ft_atoi_base.s @@ -14,103 +14,119 @@ extern _ft_strlen global _ft_atoi_base -; int ft_atoi_base(const char*, const char*); +; int ft_atoi_base(const char *str, const char *base); _ft_atoi_base: - push rbp ; save previous stackframe - mov rbp, rsp ; create new one + mov r12, rdi ; r12 = str + mov r13, rsi ; r13 = base - mov rbx, rdi ; rbx = str - mov rcx, rsi ; rcx = base - - mov rdi, rcx + ; check if the base is valid + mov rdi, r13 call _check_base cmp rax, 0 - je CHECK_BASE_ERROR + je CHECK_BASE_FALSE - mov rdi, rcx - call _ft_strlen - ;mov r8, rax ; r8 = radix - ;mov rax, r8 - xor rdx, rdx ; rdx = 0 - FT_ATOI_BASE_SPACE_LOOP: ; remove spaces - mov rdi, [rbx] - call ft_isspace + ; 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 - jne FT_ATOI_BASE_SPACE_LOOP_END - inc rbx - jmp FT_ATOI_BASE_SPACE_LOOP - FT_ATOI_BASE_SPACE_LOOP_END: + je FT_ATOI_BASE_IGNORE_SPACES + + + ; cmp byte [r12 + r15], 0x2d + ; mov r11, zf ; r11 = is negative - xor rax, rax ; rax = 0 - xor rdx, rdx ; rdx = 0 + mov rdi, r13 + call _ft_strlen + mov r14, rax ; r14 = radix + + xor rcx, rcx ; return value FT_ATOI_BASE_LOOP: - cmp byte [rbx], 30h ; while isdigit - jl FT_ATOI_BASE_END ; if *rbx < '0' jmp end - cmp byte [rbx], 39h - ja FT_ATOI_BASE_END ; if *rbx > '9' jmp end - - imul eax, 10 ; eax *= 10, shift previous digits - mov dl, byte [rbx] - and dl, 0x0F ; char to digit - add eax, edx ; insert as first digit - inc rbx + 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_END: - pop rbp + FT_ATOI_BASE_LOOP_END: + mov rax, rcx ret - + + +; rdi: char *base +; sil: char searched _base_pos: - mov rcx, rsi - xor rax, rax + mov rax, -1 BASE_POS_LOOP: - cmp byte [rdi + rax], 0 + inc rax + cmp byte [rdi + rax], 0 ; if '\0' char not in base je BASE_POS_NOT_FOUND - cmp cl, byte [rdi + rax] - je BASE_POS_FOUND - inc eax - jmp BASE_POS_LOOP + cmp sil, byte [rdi + rax] ; loop until '\0' or found + jne BASE_POS_LOOP + ret BASE_POS_NOT_FOUND: - mov eax, 0xFFFFFFFF - BASE_POS_FOUND: + mov rax, -1 ret -_check_base: - push rbx - mov rbx, rsp - - mov rbx, rdi ; rbx = str - call _ft_strlen ; f strlen(rbx) < 2 - cmp eax, 2 - jl CHECK_BASE_ERROR +; rdi: char *base +_check_base: + ; 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 [rbx], 2bh ; *rbx == '-' || *rbx == '+' - je CHECK_BASE_ERROR - cmp byte [rbx], 2dh - je CHECK_BASE_ERROR - call ft_isspace + 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_ERROR - - inc rbx - cmp byte [rbx], 0h - jne CHECK_BASE_LOOP + 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 rbx ret - CHECK_BASE_ERROR: + CHECK_BASE_FALSE: xor rax, rax - pop rbx ret -ft_isspace: - cmp byte [rdi], 20h ; if space jump next + +; dil: char c +_ft_isspace: + cmp dil, 20h ; if space jump next je ISSPACE_TRUE_END - mov dl, byte [rdi] ; if \t\n\r\v\f jump next - sub dl, 9h - cmp dl, 5h + sub dil, 9h + cmp dil, 5h jl ISSPACE_TRUE_END xor rax, rax ret diff --git a/main.c b/main.c index ff6ce3c..b89fdc8 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 02:13:29 by cacharle ### ########.fr */ +/* Updated: 2019/11/23 04:33:27 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -63,13 +63,13 @@ int main() /* g[ret] = 0; */ /* printf("%s\n", g); */ /* */ - char *h = ft_strdup("bonjour"); - printf("%s\n", h); - free(h); + /* char *h = ft_strdup("bonjour"); */ + /* printf("%s\n", h); */ + /* free(h); */ /* printf("%d\n", check_base("01")); */ - /* printf("%d\n", ft_atoi_base(" \t\v\r \n 1012h", "01")); */ + printf("%d\n", ft_atoi_base(" \t\n\r\v\f\r 010\t0101001", "01")); return 0; } -- cgit