Adds atoi

This commit is contained in:
2025-07-20 11:33:07 +02:00
parent 1c5ba65f49
commit 4ed0ae373c

View File

@@ -6,9 +6,154 @@ section .bss
cnvtBuff resb 67
cnvtBuffRev resb 67
section .text
global atoi
global itoa
global utoa
;----- atoi(*str[]) -----;
; Converts numeric string to an integer
; Return value: Converted integer or 0 if input was invalid
; Used registers:
; rax* (ret)
; rdi* (arg) Numeric string to convert
; rsi* Stores base
; rdx* Stores max usable ascii number
; rcx* Loop counter
; r8* tmp storage rsi (cmov) >> Loop counter for calculating base^n
; r9* tmp storage rdx (cmov) >> Calculated base^n
; r10* Stores return value (since RAX is used by IMUL)
atoi:
xor rax, rax
xor rcx, rcx
xor r10, r10
cmp byte [rdi], EOS
je .quit
; -- Test if negative (increase pointer to str, result is always calculated positively. Once reaching '-' again, then NEG)
cmp byte [rdi], '-'
jne .noMinusSign
inc rdi
inc rcx ;make sure .calculateLoop includes minus sign
; -- Determine base
.noMinusSign:
; hex?
mov r8, 16
cmp word [rdi], '0x'
cmove rsi, r8
je .skipBaseNotation
; octal?
mov r8, 8
mov r9, '7'
cmp word [rdi], '0o'
cmove rsi, r8
cmove rdx, r9
je .skipBaseNotation
; binary?
mov r8, 2
mov r9, '1'
cmp word [rdi], '0b'
cmove rsi, r8
cmove rdx, r9
je .skipBaseNotation
; nope, decimal
mov rsi, 10
mov rdx, '9'
jmp .getLen
.skipBaseNotation:
cmp rcx, 1 ;If '-' was found, using base is invalid
je .quit
add rdi, 2
; -- Get length of numeric string + test if valid
.getLen:
.getLenLoop:
cmp byte [rdi], EOS
je .calculate
cmp byte [rdi], '0'
jb .quit
; Test if valid
cmp rsi, 16
je .getLenLoop_testHex
cmp byte [rdi], dl
ja .quit
jmp .getLenLoop_cnt
.getLenLoop_testHex:
cmp byte [rdi], 'F'
ja .quit
cmp byte [rdi], 'A'
jb .testHex_isNum
jmp .getLenLoop_cnt
.testHex_isNum:
cmp byte [rdi], '9'
ja .quit
.getLenLoop_cnt:
inc rdi
inc rcx
jmp .getLenLoop
; -- Calculate the number
.calculate:
dec rdi ;don't point to EOS
xor r8, r8
.calculateLoop:
cmp byte [rdi], '-'
je .wrapup_neg
; Calculate base^n
.calcBase:
test r8, r8
jz .calcBase_firstLoop
cmp r8, 1
je .calcBase_secondLoop
jmp .calcBase_otherLoops
.calcBase_firstLoop:
mov r9, 1
jmp .calcNum
.calcBase_secondLoop:
mov r9, rsi
jmp .calcNum
.calcBase_otherLoops:
mov rax, rsi
mov r9, r8
dec r9
.calcBaseLoop:
imul rsi
dec r9
test r9, r9
jnz .calcBaseLoop
mov r9, rax
; Calculate number
.calcNum:
xor rax, rax
mov al, byte [rdi]
cmp al, 'A'
jb .calcNum_notHex
sub al, 55 ;'A'-10 (65-10)
jmp .calcNum_cnt
.calcNum_notHex:
sub al, '0'
.calcNum_cnt:
imul r9
add r10, rax
dec rdi
inc r8
loop .calculateLoop
jmp .quit
.wrapup_neg:
neg r10
.quit:
mov rax, r10
ret
;----- itoa(int, base, padLen, bool padZeroes) -----;
; Converts a signed integer to a string
; Return value: Pointer to converted string or 0(EOS) if entered base is invalid