global ft_atoi_base global check_duplicate_char extern ft_strlen section .data invalid_chars: db "+- ", 0x0c, 0x0a, 0x0d, 0x09, 0x0b, 0 whitespaces: db " ", 0x0c, 0x0a, 0x0d, 0x09, 0x0b, 0 section .text ; checks if a char is in the invalid_chars get_char_index: xor rax, rax push rsi get_char_index_loop: cmp dil, [rsi] ;is char invalid je get_char_index_found mov al, [rsi] ; is end of string test al, al lea rsi, [rsi + 1] jne get_char_index_loop mov rax, -1 ;not found and at the end pop rsi ret get_char_index_found: pop rax ;return index of the found char sub rsi, rax mov rax, rsi ret ;function that ... it's in the name why are you looking here ; parameters : the string in rdi ; returns 1 if there is a duplicate char check_duplicate_char: mov al ,[rdi] ; test if \0 test al, al je no_duplicate push rdi mov rsi, rdi lea rsi, [rsi + 1] mov dil, [rdi] call get_char_index pop rdi cmp rax, -1 ;is char found lea rdi, [rdi + 1] je check_duplicate_char mov rax, 1 ret no_duplicate: xor rax, rax ret ;function that checks if the base is valid ;a valid base does not have any of these char : "+-" or any space defined by isspace(3) and does not have any duplicate char or does not have any char ; returns 0 if base is not valid check_base: xor rax, rax mov al, [rdi] ; check if it's an empty string test al, al jne chk_bs_duplicate xor rax, rax ret chk_bs_duplicate: push rdi call check_duplicate_char pop rdi test rax, rax je chk_bs_char xor rax, rax ret chk_bs_char: mov al, [rdi] ; if rdi is \0, return 0 test al, al je base_ok push rdi ; if current char is in invalid_chars mov dil, [rdi]; lea rsi, [rel invalid_chars] call get_char_index pop rdi cmp rax, -1 ; if not -1, error lea rdi, [rdi + 1] je chk_bs_char xor rax, rax; return 0 ret base_ok: mov rax,1 ret ; prototype : int ft_atoi_base(char *str, char *base) ; rdi str ; rsi base ft_atoi_base: xor rax, rax ;check if there is a null pointer in rdi or rsi test rdi, rdi je final_number test rsi, rsi je final_number push rdi ; is base valid push rsi mov rdi, rsi call check_base pop rsi pop rdi test rax, rax jne whitespace_skip ; if 0 , base is not valid xor rax, rax ret xor rdx, rdx whitespace_skip_inc: lea rdi, [rdi + 1] whitespace_skip: push rdi push rsi mov dil, [rdi] lea rsi, [rel whitespaces] call get_char_index pop rsi pop rdi cmp rax, 0 jge whitespace_skip_inc jmp plus_minus plus_minus_invert: xor rdx, 1 plus_minus_inc: lea rdi, [rdi + 1] plus_minus: mov al, [rdi] cmp al, '-' je plus_minus_invert cmp al, '+' je plus_minus_inc push rdi push rsi mov rdi, rsi call ft_strlen pop rsi pop rdi mov rbx, rax xor rax, rax push rdx number_loop: mov dl, [rdi] test dl, dl je final_number push rax push rdi push rsi mov dil, dl call get_char_index pop rsi pop rdi mov rdx, rax ; save return value in rdx pop rax cmp rdx, -1 je final_number push rdx ; imul sets rdx to 0 imul rbx pop rdx add rax, rdx lea rdi, [rdi + 1] jmp number_loop final_number: pop rdx test rdx, rdx jne neg_final_number ret neg_final_number: neg rax ret