Adds atoi
This commit is contained in:
145
src/convert.asm
145
src/convert.asm
@@ -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
|
||||
|
Reference in New Issue
Block a user