global ft_atoi_base extern malloc ; for LUT extern free ; for LUT ft_atoi_base: push rsp push rbx push r12 ; sign push r13 ; base push r14 ; return value push r15 ; base LUT push rdi push rsi mov rdi, 128 call malloc WRT ..plt mov r15, rax pop rsi pop rdi push rdi push rsi xor rcx, rcx .init_lut_loop: ; sets LUT to 0 cmp rcx, 128 je .set_base mov byte [r15 + rcx], 0 inc rcx jmp .init_lut_loop .set_base: xor rcx, rcx ; rcx is base length/count .set_base_loop: cmp byte [rsi + rcx], 0 je .check_base_len cmp byte [rsi + rcx], 43 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], 0 jne .error mov rdx, rcx inc rdx mov byte [r15 + rbx], dl 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 .pos_once: inc rcx jmp .get_sign_loop .neg_once: neg r12 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, 0 je .done mov rax, r14 mul r13 mov r14, rax dec rbx add r14, rbx inc rcx jmp .get_number_loop .error: mov r14, 0 .done: mov rdi, r15 call free WRT ..plt mov rax, r14 cmp r12, 1 je .exit neg rax .exit: pop rsi pop rdi pop r15 pop r14 pop r13 pop r12 pop rbx pop rsp ret