; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. ; ; int strtol(const char *str, int base) ; ; rax = integer extracted from str ; rdx = pointer to first invalid byte ; strtol: mov ax2, 1 jmp strtoq ; ; int strtoul(const char *str, int base) ; ; rax = integer extracted from str ; rdx = pointer to first invalid byte ; strtoul: nul ax2 jmp strtoq ; ; int strtoq(const char *str, int base, bool signed) ; ; guesses base when 'base'=0 ; strtoq: nul rax, rsi mov rdx, ax0 ; make sure base is in [2, 32] beq ax1, 1, .bad bltu 36, ax1, .bad ; empty string? bzr b[rdx], .done .skip_spc: bne b[rdx], ' ', .no_spc inc rdx jmp .skip_spc .no_spc: ; skip + bne b[rdx], '+', .no_plus inc rdx .no_plus: ; unsigned? bzr ax2, .unsigned ; parse '-' bne b[rdx], '-', .unsigned inc rdx mov rsi, 1 .unsigned: ; base 0 bzr ax1, .base_0 ; base prefix? bne b[rdx], '0', .main_loop inc rdx movzx rcx, b[rdx] ; "0x"/"0b" prefix jrcxz .done ; "0" beq rcx, 'x', .parsed_0x beq rcx, 'b', .parsed_0b ; may be octal, but we don't care ; we accept "0110101010" (despite base=2) for instance jmp .main_loop .parsed_0x: ; are we in base 16? ; if not, leave rax = 0 and *rdx = 'x' bne ax1, 16, .done ; else inc rdx jmp .main_loop .parsed_0b: ; are we in base 2? ; if not, leave rax = 0 and *rdx = 'b' bne ax1, 2, .done ; else inc rdx jmp .main_loop .base_0: ; guess base beq b[rdx], '0', .b0_not10 ; must be base 10 mov ax1, 10 jmp .main_loop .b0_not10: inc rdx bne b[rdx], 'x', .b0_not16 inc rdx mov ax1, 16 jmp .main_loop .b0_not16: bne b[rdx], 'b', .b0_not2 inc rdx mov ax1, 2 jmp .main_loop .b0_not2: ; take octal by default mov ax1, 8 .main_loop: movzx rcx, b[rdx] inc rdx ; between 0 and 9? bltu rcx, '0', .done bltu '9', rcx, .not_digit10 ; yes sub rcx, '0' jmp .next .not_digit10: bltu rcx, 'A', .done bltu 'Z', rcx, .not_digitAZ sub rcx, 55 ; 'A' - 10 jmp .next .not_digitAZ: bltu rcx, 'a', .done bltu 'z', rcx, .done sub rcx, 87 ; 'a' - 10 jmp .next .next: ; too large for base? blteu ax1, rcx, .done mul rax, ax1 add rax, rcx jmp .main_loop .done: ; negative? bzr rsi, .r ; yes neg rax .r: ret .bad: ret