Adds atoi
This commit is contained in:
145
src/convert.asm
145
src/convert.asm
@@ -6,9 +6,154 @@ section .bss
|
|||||||
cnvtBuff resb 67
|
cnvtBuff resb 67
|
||||||
cnvtBuffRev resb 67
|
cnvtBuffRev resb 67
|
||||||
section .text
|
section .text
|
||||||
|
global atoi
|
||||||
global itoa
|
global itoa
|
||||||
global utoa
|
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) -----;
|
;----- itoa(int, base, padLen, bool padZeroes) -----;
|
||||||
; Converts a signed integer to a string
|
; Converts a signed integer to a string
|
||||||
; Return value: Pointer to converted string or 0(EOS) if entered base is invalid
|
; Return value: Pointer to converted string or 0(EOS) if entered base is invalid
|
||||||
|
Reference in New Issue
Block a user