global ft_atoi_base extern malloc ; for LUT extern free ; for LUT ft_atoi_base: push rbx push r12 ; sign push r13 ; base push r14 ; return value push r15 ; base LUT push rdi push rsi mov rdi, 256 call malloc WRT ..plt mov r15, rax pop rsi pop rdi cmp r15, 0 jz .malloc_error xor rcx, rcx .init_lut_loop: ; sets LUT to 0 cmp rcx, 256 je .set_base mov byte [r15 + rcx], -1 inc rcx jmp .init_lut_loop .set_base: xor rcx, rcx ; rcx is base length/count .set_base_loop: cmp byte [rsi + rcx], 0 ; end of base je .check_base_len cmp byte [rsi + rcx], 43 ; check forbidden chars je .error cmp byte [rsi + rcx], 45 je .error cmp byte [rsi + rcx], 126 jg .error cmp byte [rsi + rcx], 33 jl .error xor rbx, rbx mov bl, byte [rsi + rcx] cmp byte [r15 + rbx], -1 ; check double digits in base jne .error mov rdx, rcx mov byte [r15 + rbx], dl ; set base number in LUT inc rcx jmp .set_base_loop .check_base_len: cmp rcx, 2 jl .error mov r13, rcx xor rcx, rcx ; index = 0 xor r14, r14 ; number = 0 mov r12, 1 ; sign = 0 .skip_white_spaces: cmp byte [rdi + rcx], 33 jle .skip_once cmp byte [rdi + rcx], 126 jg .skip_once jmp .get_sign_loop .skip_once: inc rcx jmp .skip_white_spaces .get_sign_loop: cmp byte [rdi + rcx], 43 je .pos_once cmp byte [rdi + rcx], 45 je .neg_once jmp .get_number_loop .neg_once: neg r12 .pos_once: inc rcx jmp .get_sign_loop .get_number_loop: xor rbx, rbx mov bl, byte [rdi + rcx] cmp bl, 0 je .done mov bl, byte [r15 + rbx] ; set bl to base index cmp bl, -1 je .done mov rax, r14 mul r13 mov r14, rax add r14, rbx inc rcx jmp .get_number_loop .malloc_error: mov rax, 0 jmp .exit .error: mov r14, 0 .done: mov rdi, r15 call free WRT ..plt mov rax, r14 cmp r12, 1 ; check sign je .exit neg rax .exit: pop r15 pop r14 pop r13 pop r12 pop rbx ret