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 ; skip whitespace and sign ; rdi: str ; return: ; rax str + x + is_signed ; dl is_signed 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 xor dl, dl pop r12 cmp byte [rax], '-' je .is_signed ret .is_signed: inc dl inc rax ret ; rdi: base ; rsi: char ; rdx: baselen ; int i = 0 ; while i < baselen ; if (c == base[i]) ; return base[i] ; inc i ; return -1 get_num_from_base: xor rax, rax .loop: cmp rax, rdx jge .not_found mov cl, byte [rdi + rax] cmp cl, sil je .found inc rax jmp .loop .found: 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 xor r11, r11 .loop: cmp byte [r12], 0 je .end_loop mov rdi, r13 movzx rsi, byte [r12] mov rdx, r14 push r11 call get_num_from_base pop r11 test rax, rax jl .end_loop imul r11d, r14d jo .overflow add r11, rax jc .overflow inc r12 jmp .loop .end_loop: mov rax, r11 .done: test r15b, r15b je .cleanup neg rax .cleanup: 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: call __errno_location wrt ..plt mov dword [rax], 34 xor rax, rax jmp .cleanup