; 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: sub ax2, ax2 jmp strtoq ; ; int strtoq(const char *str, int base, bool signed) ; ; guesses base when 'base'=0 ; strtoq: xor rax, rax mov rdx, ax0 ; make sure base is in [2, 32] cmp ax1, 1 j.z .bad cmp ax1, 36 j.a .bad ; empty string? cmp b[rdx], 0 jmp.z .done .skip_spc: cmp b[rdx], ' ' inc.z rdx jmp.z .skip_spc ; skip + cmp b[rdx], '+' inc.z rdx ; signed? test ax2, ax2 sub.z lx1, lx1 jmp.z .unsigned ; parse '-' cmp b[rdx], '-' inc.z rdx mov.z lx1, 1 sub.nz lx1, lx1 .unsigned: ; base 0 test ax1, ax1 jmp.z .base_0 ; base prefix? cmp b[rdx], '0' jmp.nz .main_loop inc rdx ; string is "0" cmp b[rdx], 0 jmp.z .done ; "0x" prefix cmp b[rdx], 'x' jmp.z .parsed_0x ; "0b" prefix cmp b[rdx], 'b' jmp.z .parsed_0b ; may be octal, but we don't care ; we accept "0110101010" (binary) for instance jmp .main_loop .parsed_0x: ; are we in base 16? ; if not, leave rax = 0 and *rdx = 'x' cmp ax1, 16 jmp.nz .done ; else inc rdx jmp .main_loop .parsed_0b: ; are we in base 2? ; if not, leave rax = 0 and *rdx = 'b' cmp ax1, 2 jmp.nz .done ; else inc rdx jmp .main_loop .base_0: ; guess base cmp b[rdx], '0' mov.nz ax1, 10 jmp.nz .main_loop inc rdx cmp b[rdx], 'x' inc.z rdx mov.z ax1, 16 jmp.z .main_loop cmp b[rdx], 'b' inc.z rdx mov.z ax1, 2 jmp.z .main_loop mov ax1, 8 .main_loop: mov lx0, b[rdx] inc rdx cmp lx0, '0' jmp.b .done cmp.ae lx0, '9' sub.be lx0, '0' jmp.be .next cmp lx0, 'A' cmp.ae lx0, 'Z' sub.be lx0, 55 ; 'A' - 10 jmp.be .next cmp lx0, 'a' jmp.b .next cmp.ae lx0, 'z' sub.be lx0, 87 ; 'a' - 10 jmp.be .next .next: ; too large for base? cmp lx0, ax1 jmp.ae .done mul rax, ax1 add rax, lx0 jmp .main_loop .done: ; negative? test lx1, lx1 ret.z ; yes neg rax ret .bad: mov q[errno], EINVAL ret