; 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) ; ; eax = integer extracted from str ; edx = pointer to first invalid byte ; strtol: mov ax2, 1 jmp strtoq ; ; int strtoul(const char *str, int base) ; ; eax = integer extracted from str ; edx = 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 eax, esi mov edx, ax0 ; make sure base is in [2, 32] beq ax1, 1, .bad bltu 36, ax1, .bad ; empty string? bzr b[edx], .done .skip_spc: bne b[edx], ' ', .no_spc inc edx jmp .skip_spc .no_spc: ; skip + bne b[edx], '+', .no_plus inc edx .no_plus: ; unsigned? bzr ax2, .unsigned ; parse '-' bne b[edx], '-', .unsigned inc edx mov esi, 1 .unsigned: ; base 0 bzr ax1, .base_0 ; base prefix? bne b[edx], '0', .main_loop inc edx movzx ecx, b[edx] ; "0x"/"0b" prefix jecxz .done ; "0" beq ecx, 'x', .parsed_0x beq ecx, '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 eax = 0 and *edx = 'x' bne ax1, 16, .done ; else inc edx jmp .main_loop .parsed_0b: ; are we in base 2? ; if not, leave eax = 0 and *edx = 'b' bne ax1, 2, .done ; else inc edx jmp .main_loop .base_0: ; guess base beq b[edx], '0', .b0_not10 ; must be base 10 mov ax1, 10 jmp .main_loop .b0_not10: inc edx bne b[edx], 'x', .b0_not16 inc edx mov ax1, 16 jmp .main_loop .b0_not16: bne b[edx], 'b', .b0_not2 inc edx mov ax1, 2 jmp .main_loop .b0_not2: ; take octal by default mov ax1, 8 .main_loop: movzx ecx, b[edx] inc edx ; between 0 and 9? bltu ecx, '0', .done bltu '9', ecx, .not_digit10 ; yes sub ecx, '0' jmp .next .not_digit10: bltu ecx, 'A', .done bltu 'Z', ecx, .not_digitAZ sub ecx, 55 ; 'A' - 10 jmp .next .not_digitAZ: bltu ecx, 'a', .done bltu 'z', ecx, .done sub ecx, 87 ; 'a' - 10 jmp .next .next: ; too large for base? blteu ax1, ecx, .done mul eax, ax1 add eax, ecx jmp .main_loop .done: ; negative? bzr esi, .r ; yes neg eax .r: ret .bad: ret