From f8c8321615405260124d941b22952f9d6276a410 Mon Sep 17 00:00:00 2001 From: lohhiiccc Date: Fri, 12 Jun 2026 19:43:12 +0200 Subject: [PATCH] feat: atoibase skel --- src/ft_atoibase.asm | 249 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 src/ft_atoibase.asm diff --git a/src/ft_atoibase.asm b/src/ft_atoibase.asm new file mode 100644 index 0000000..f67fa03 --- /dev/null +++ b/src/ft_atoibase.asm @@ -0,0 +1,249 @@ +global ft_atoibase +extern ft_bzero +extern ft_isspace +extern __errno_location + +section .text + +;int has_dup(const char *s) { +; uint32_t bits[8] = {0}; // 8*32 = 256 bits +; for (const unsigned char *p = (const unsigned char*)s; *p; ++p) { +; unsigned int v = *p; +; unsigned int idx = v >> 5; // division par 32 +; unsigned int bit = v & 31; // v % 32 +; uint32_t mask = 1u << bit; +; if (bits[idx] & mask) return -1; +; bits[idx] |= mask; +; } +; return 0; +;} + +; return base_len and check for "-+" or duplicate char +; rdi: base +check_base: + ; uint32_t buffer[8] + push rbp + mov rbp, rsp + sub rsp, 40 + + mov qword [rsp + 32], rdi + + ; bzero buffer, 32 + mov rdi, rsp + mov rsi, 32 + call ft_bzero wrt ..plt + + mov rax, qword [rsp + 32] + +.loop: + mov dl, byte [rax] + test dl, dl + je .done + + ; if (*p == '-' || *p == '+') return -1 + cmp dl, 45 ; '-' + je .error + cmp dl, 43 ; '+' + je .error + + ; r10(idx) = *p / 32 + ; rdx(bit) = *p % 32 + mov r10, [rax] + shr r10, 5 + mov rdx, [rax] + and rdx, 31 + + ; mask = 1 << rdx(bit) + mov r11, 1 + mov cl, dl + shl r11, cl + + ; if (bits[idx] & mask) return -1 + mov r9, [rsp + rdx] + and r9, r11 + test r9, r9 + jne .error + + ; bits[idx] |= mask + or [rsp + rdx], r11 + + ; ++p + inc rax + + jmp .loop +.done: + sub rax, qword [rsp + 32] + +.return: + add rsp, 40 + pop rbp + ret + +.error: + mov rax, -1 + jmp .return + +; rdi: str +; skip whitespace +; return : +; rax str + x +; dl is_signed +; rax = 0 if 2 sign +find_start: + push r12 + mov r12, rdi +.loop: + mov dil, byte [r12] + call ft_isspace wrt ..plt + + test rax, rax + je .done + test dil, dil + je .done + + inc r12 + jmp .loop +.done: + mov rax, r12 + mov dl, 0 + + pop r12 + + cmp byte [rax], '-' + je .is_signed + + ret +.is_signed: + inc dl + inc rax + ret + +; rdi base +; rsi char +is_in_base: +.loop: + mov dl, byte [rdi] + test dl, dl + je .is_not_in + + cmp dl, sil + je .is_in + + inc rdi + jmp .loop + +.is_in: + mov rax, 1 + ret + +.is_not_in: + xor rax, rax + ret + +; rdi: base +; rsi: char +; rdx: baselen + +; int i = 0 +; while i < baselen +; if (c == base[i]) +; return 1 +; inc i +; return -1 + +get_num_from_base: + xor rax, rax; rax = i = 0 + +.loop: + cmp rax, rdx + jge .not_found + + mov cl, byte [rdi + rax] + cmp cl, sil + je .found + + inc rax + jmp .loop + +.found: + mov rax, 1 + ret + +.not_found: + mov rax, -1 + ret + +; r12: str +; r13: base +ft_atoibase: + push r12 + push r13 + push r14 + push r15 + + mov r12, rdi + mov r13, rsi + + ; if (check_base(base) <= 0 ) return 0; + mov rdi, r13 + call check_base + test rax, rax + jle .invalid_base + + ; r14 = base_len + mov r14, rax + + ; str += start + is_signed + ; rb9 = is_signed + mov rdi, r12 + call find_start + mov r12, rax + mov r15b, dl + + ; r11 = r = 0 + xor r11, r11 +.loop: + cmp byte [r12], 0 + je .done + + + mul r11, r14 + mov rdi, r13 + movzx rsi, byte [r12] + mov rdx, r14 + + push r11 + call get_num_from_base + pop r11 + cmp rax, rax + jl .done + + add r11, rax + ; r += rax + + inc r12 + jmp .loop +.done: + mov rax, r11 + + test r9b, r9b + je .pos + neg rax +.pos: + + pop r12 + pop r13 + pop r14 + pop r15 + ret + +.invalid_base: + ; errno = EINVAL + call __errno_location wrt ..plt + mov dword [rax], 22 + xor rax, rax + jmp .done + +.overflow: + xor rax, rax ; TODO: LONG_MAX | LONG_MIN + jmp .done