1) atoi: signed+unsigned overflow checks (JC,JO) 2) correct values for MIN_INTxx constants
This commit is contained in:
@@ -14,10 +14,10 @@ MAX_UINT32 equ 0xFFFFFFFF
|
|||||||
MAX_UINT16 equ 0xFFFF
|
MAX_UINT16 equ 0xFFFF
|
||||||
MAX_UINT8 equ 0xFF
|
MAX_UINT8 equ 0xFF
|
||||||
|
|
||||||
MIN_INT64 equ ~0x7FFFFFFFFFFFFFFF
|
MIN_INT64 equ ~MAX_INT64 + 1
|
||||||
MIN_INT32 equ ~0x7FFFFFFF
|
MIN_INT32 equ ~MAX_INT32 + 1
|
||||||
MIN_INT16 equ ~0x7FFF
|
MIN_INT16 equ ~MAX_INT16 + 1
|
||||||
MIN_INT8 equ ~0x7F
|
MIN_INT8 equ ~MAX_INT8 + 1
|
||||||
|
|
||||||
MAX_INT64 equ 0x7FFFFFFFFFFFFFFF
|
MAX_INT64 equ 0x7FFFFFFFFFFFFFFF
|
||||||
MAX_INT32 equ 0x7FFFFFFF
|
MAX_INT32 equ 0x7FFFFFFF
|
||||||
|
@@ -22,16 +22,19 @@ section .text
|
|||||||
; r8* tmp storage rsi (cmov) >> Loop counter for calculating base^n
|
; r8* tmp storage rsi (cmov) >> Loop counter for calculating base^n
|
||||||
; r9* tmp storage rdx (cmov) >> Calculated base^n
|
; r9* tmp storage rdx (cmov) >> Calculated base^n
|
||||||
; r10* Stores return value (since RAX is used by IMUL)
|
; r10* Stores return value (since RAX is used by IMUL)
|
||||||
|
; r11* Stores if input is signed (r11b=1) or unsigned (r11b=0) ('-')
|
||||||
atoi:
|
atoi:
|
||||||
xor rax, rax
|
xor rax, rax
|
||||||
xor rcx, rcx
|
xor rcx, rcx
|
||||||
xor r10, r10
|
xor r10, r10
|
||||||
|
xor r11b, r11b
|
||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .quit
|
je .quit
|
||||||
|
|
||||||
; -- Test if negative (increase pointer to str, result is always calculated positively. Once reaching '-' again, then NEG)
|
; -- Test if negative (increase pointer to str, result is always calculated positively. Once reaching '-' again, then NEG)
|
||||||
cmp byte [rdi], '-'
|
cmp byte [rdi], '-'
|
||||||
jne .noMinusSign
|
jne .noMinusSign
|
||||||
|
inc r11b
|
||||||
inc rdi
|
inc rdi
|
||||||
inc rcx ;make sure .calculateLoop includes minus sign
|
inc rcx ;make sure .calculateLoop includes minus sign
|
||||||
|
|
||||||
@@ -61,8 +64,8 @@ atoi:
|
|||||||
mov rdx, '9'
|
mov rdx, '9'
|
||||||
jmp .getLenLoop
|
jmp .getLenLoop
|
||||||
.skipBaseNotation:
|
.skipBaseNotation:
|
||||||
cmp rcx, 1 ;If '-' was found, using base is invalid
|
test r11b, r11b;If '-' was found, using base is invalid
|
||||||
je .quit
|
jnz .quit
|
||||||
add rdi, 2
|
add rdi, 2
|
||||||
|
|
||||||
; -- Get length of numeric string + test if valid
|
; -- Get length of numeric string + test if valid
|
||||||
@@ -149,14 +152,15 @@ atoi:
|
|||||||
|
|
||||||
.calcNum_cnt:
|
.calcNum_cnt:
|
||||||
imul r9
|
imul r9
|
||||||
|
test r11b, r11b
|
||||||
mov rdx, -1
|
jz .checkUnsignedOverflow
|
||||||
sub rdx, r10
|
|
||||||
cmp rax, rdx
|
|
||||||
;TODO: Add signed checks
|
|
||||||
ja .overflow
|
|
||||||
|
|
||||||
add r10, rax
|
add r10, rax
|
||||||
|
jo .overflow
|
||||||
|
jmp .continue
|
||||||
|
.checkUnsignedOverflow:
|
||||||
|
add r10, rax
|
||||||
|
jc .overflow
|
||||||
|
.continue:
|
||||||
dec rdi
|
dec rdi
|
||||||
inc r8
|
inc r8
|
||||||
loop .calculateLoop
|
loop .calculateLoop
|
||||||
|
@@ -345,6 +345,10 @@ section .rodata
|
|||||||
addTest(atoi7, "atoi(''0b00010111'')") ;23
|
addTest(atoi7, "atoi(''0b00010111'')") ;23
|
||||||
addTest(atoi8, "atoi(''0b02010111'')") ;0
|
addTest(atoi8, "atoi(''0b02010111'')") ;0
|
||||||
addTest(atoi9, "atoi(''0xabcdefg'')") ;0
|
addTest(atoi9, "atoi(''0xabcdefg'')") ;0
|
||||||
|
addTest(atoi10, "atoi(''18446744073709551615'')") ;MAX_UINT64
|
||||||
|
addTest(atoi11, "atoi(''18446744073709551616'')") ;0
|
||||||
|
addTest(atoi12, "atoi('-9223372036854775807''')") ;MIN_INT64
|
||||||
|
addTest(atoi13, "atoi('-9223372036854775809''')") ;0
|
||||||
atoiStr1 db "079168045",EOS
|
atoiStr1 db "079168045",EOS
|
||||||
atoiStr2 db "-079168045",EOS
|
atoiStr2 db "-079168045",EOS
|
||||||
atoiStr3 db "-0xABCDEF",EOS
|
atoiStr3 db "-0xABCDEF",EOS
|
||||||
@@ -354,6 +358,10 @@ section .rodata
|
|||||||
atoiStr7 db "0b00010111",EOS
|
atoiStr7 db "0b00010111",EOS
|
||||||
atoiStr8 db "0b02010111",EOS
|
atoiStr8 db "0b02010111",EOS
|
||||||
atoiStr9 db "0xabcdefg",EOS
|
atoiStr9 db "0xabcdefg",EOS
|
||||||
|
atoiStr10 db "18446744073709551615",EOS
|
||||||
|
atoiStr11 db "18446744073709551616",EOS
|
||||||
|
atoiStr12 db "-9223372036854775807",EOS
|
||||||
|
atoiStr13 db "-9223372036854775809",EOS
|
||||||
;itoa()
|
;itoa()
|
||||||
addTestHeader(_itoa, "itoa")
|
addTestHeader(_itoa, "itoa")
|
||||||
addTest(itoa1, "// See printf outputs")
|
addTest(itoa1, "// See printf outputs")
|
||||||
@@ -1297,6 +1305,30 @@ _start:
|
|||||||
lea rdi, [rel atoiStr9]
|
lea rdi, [rel atoiStr9]
|
||||||
call atoi
|
call atoi
|
||||||
assert_u_eq(0)
|
assert_u_eq(0)
|
||||||
|
|
||||||
|
; TEST 10
|
||||||
|
printTest(atoi10)
|
||||||
|
lea rdi, [rel atoiStr10]
|
||||||
|
call atoi
|
||||||
|
assert_u_eq(MAX_UINT64)
|
||||||
|
|
||||||
|
; TEST 11
|
||||||
|
printTest(atoi11)
|
||||||
|
lea rdi, [rel atoiStr11]
|
||||||
|
call atoi
|
||||||
|
assert_eq(0)
|
||||||
|
|
||||||
|
; TEST 12
|
||||||
|
printTest(atoi12)
|
||||||
|
lea rdi, [rel atoiStr12]
|
||||||
|
call atoi
|
||||||
|
assert_eq(MIN_INT64)
|
||||||
|
|
||||||
|
; TEST 13
|
||||||
|
printTest(atoi13)
|
||||||
|
lea rdi, [rel atoiStr13]
|
||||||
|
call atoi
|
||||||
|
assert_eq(0)
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
;--- itoa()
|
;--- itoa()
|
||||||
|
Reference in New Issue
Block a user