; Internal register assignments: ; r1 - Partially parsed output integer ; r2 - Parsing position ; r3 - Character being parsed ; r4 - Set to -1 if the input is negative ; Convert string to integer (akin to libc atoi(), strotoi()) ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read ; r4 - Negative marker ; Note: Unless the input is "0", tail-calls into a base-specific specialization. pub auto: mov r2, r1 mov r1, 0 mov r4, 0 load_8 r3, [r2] cmp r3, 0x2D ; '-' jne auto_positive sub r4, zr, 1 ; Set r4 to -1 add r2, r2, 1 auto_positive: load_16 r3, [r2] ; 2-byte prefix "0b", "0o", "0x", etc. or r3, r3, 0x20 ; 2nd char to lower case add r2, r2, 2 cmp r3, 0x3062 ; "0b" je bin_loop cmp r3, 0x306F ; "0o" je oct_loop cmp r3, 0x3078 ; "0x" je hex_loop sub r2, r2, 2 ; no matching prefix, move pointer back jmp dec_loop ; Epilogue done: add r1, r1, r4 ; If r4 is -1, negate r1. Else it's 0 and no effect. xor r1, r1, r4 mov flags, 0 ; No error jmp r13 ; Convert decimal string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read ; r4 - Negative marker pub dec: mov r2, r1 mov r1, 0 mov r4, 0 load_8 r3, [r2] cmp r3, 0x2D ; '-' jne dec_positive sub r4, zr, 1 ; Set r4 to -1 add r2, r2, 1 dec_loop: load_8 r3, [r2] dec_positive: sub r3, r3, 0x30 ; '0' cmp r3, 9 ja done add r2, r2, 1 lsl flags, r1, 2 ; Use flags to help multiply by 10 add r1, r1, flags lsl r1, r1, 1 add r1, r1, r3 jmp dec_loop ; Convert binary string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read ; r4 - Negative marker pub bin: mov r2, r1 mov r1, 0 mov r4, 0 load_8 r3, [r2] cmp r3, 0x2D ; '-' jne bin_positive sub r4, zr, 1 ; Set r4 to -1 add r2, r2, 1 bin_positive: load_16 r3, [r2] ; check for prefix or r3, r3, 0x20 ; 2nd char to lower case cmp r3, 0x3062 ; "0b" jne bin_loop add r2, r2, 2 bin_loop: load_8 r3, [r2] sub r3, r3, 0x30 ; '0' cmp r3, 1 ja done add r2, r2, 1 lsl r1, r1, 1 add r1, r1, r3 jmp bin_loop ; Convert octal string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read ; r4 - Negative marker pub oct: mov r2, r1 mov r1, 0 mov r4, 0 load_8 r3, [r2] cmp r3, 0x2D ; '-' jne oct_positive sub r4, zr, 1 ; Set r4 to -1 add r2, r2, 1 oct_positive: load_16 r3, [r2] ; check for prefix or r3, r3, 0x20 ; 2nd char to lower case cmp r3, 0x306F ; "0o" jne oct_loop add r2, r2, 2 oct_loop: load_8 r3, [r2] sub r3, r3, 0x30 ; '0' cmp r3, 7 ja done add r2, r2, 1 lsl r1, r1, 3 add r1, r1, r3 jmp oct_loop ; Convert hexadecimal string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read ; r4 - Negative marker pub hex: mov r2, r1 mov r1, 0 mov r4, 0 load_8 r3, [r2] cmp r3, 0x2D ; '-' jne hex_positive sub r4, zr, 1 ; Set r4 to -1 add r2, r2, 1 hex_positive: load_16 r3, [r2] ; check for prefix or r3, r3, 0x20 ; 2nd char to lower case cmp r3, 0x3078 ; "0x" jne hex_loop add r2, r2, 2 hex_loop: load_8 r3, [r2] sub r3, r3, 0x30 ; '0' cmp r3, 10 jb hex_add sub r3, r3, 0x11 ; 'A' - '0' and r3, r3, 0xdf ; to lower case cmp r3, 5 ; 0-5: 6 letters ja done add r3, r3, 10 ; Adjust for digits below hex_add: add r2, r2, 1 lsl r1, r1, 4 add r1, r1, r3 jmp hex_loop