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_UINT8 equ 0xFF
|
||||
|
||||
MIN_INT64 equ ~0x7FFFFFFFFFFFFFFF
|
||||
MIN_INT32 equ ~0x7FFFFFFF
|
||||
MIN_INT16 equ ~0x7FFF
|
||||
MIN_INT8 equ ~0x7F
|
||||
MIN_INT64 equ ~MAX_INT64 + 1
|
||||
MIN_INT32 equ ~MAX_INT32 + 1
|
||||
MIN_INT16 equ ~MAX_INT16 + 1
|
||||
MIN_INT8 equ ~MAX_INT8 + 1
|
||||
|
||||
MAX_INT64 equ 0x7FFFFFFFFFFFFFFF
|
||||
MAX_INT32 equ 0x7FFFFFFF
|
||||
|
@@ -22,16 +22,19 @@ section .text
|
||||
; 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)
|
||||
; r11* Stores if input is signed (r11b=1) or unsigned (r11b=0) ('-')
|
||||
atoi:
|
||||
xor rax, rax
|
||||
xor rcx, rcx
|
||||
xor r10, r10
|
||||
xor r11b, r11b
|
||||
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 r11b
|
||||
inc rdi
|
||||
inc rcx ;make sure .calculateLoop includes minus sign
|
||||
|
||||
@@ -61,8 +64,8 @@ atoi:
|
||||
mov rdx, '9'
|
||||
jmp .getLenLoop
|
||||
.skipBaseNotation:
|
||||
cmp rcx, 1 ;If '-' was found, using base is invalid
|
||||
je .quit
|
||||
test r11b, r11b;If '-' was found, using base is invalid
|
||||
jnz .quit
|
||||
add rdi, 2
|
||||
|
||||
; -- Get length of numeric string + test if valid
|
||||
@@ -149,14 +152,15 @@ atoi:
|
||||
|
||||
.calcNum_cnt:
|
||||
imul r9
|
||||
|
||||
mov rdx, -1
|
||||
sub rdx, r10
|
||||
cmp rax, rdx
|
||||
;TODO: Add signed checks
|
||||
ja .overflow
|
||||
|
||||
test r11b, r11b
|
||||
jz .checkUnsignedOverflow
|
||||
add r10, rax
|
||||
jo .overflow
|
||||
jmp .continue
|
||||
.checkUnsignedOverflow:
|
||||
add r10, rax
|
||||
jc .overflow
|
||||
.continue:
|
||||
dec rdi
|
||||
inc r8
|
||||
loop .calculateLoop
|
||||
|
@@ -345,6 +345,10 @@ section .rodata
|
||||
addTest(atoi7, "atoi(''0b00010111'')") ;23
|
||||
addTest(atoi8, "atoi(''0b02010111'')") ;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
|
||||
atoiStr2 db "-079168045",EOS
|
||||
atoiStr3 db "-0xABCDEF",EOS
|
||||
@@ -354,6 +358,10 @@ section .rodata
|
||||
atoiStr7 db "0b00010111",EOS
|
||||
atoiStr8 db "0b02010111",EOS
|
||||
atoiStr9 db "0xabcdefg",EOS
|
||||
atoiStr10 db "18446744073709551615",EOS
|
||||
atoiStr11 db "18446744073709551616",EOS
|
||||
atoiStr12 db "-9223372036854775807",EOS
|
||||
atoiStr13 db "-9223372036854775809",EOS
|
||||
;itoa()
|
||||
addTestHeader(_itoa, "itoa")
|
||||
addTest(itoa1, "// See printf outputs")
|
||||
@@ -1297,6 +1305,30 @@ _start:
|
||||
lea rdi, [rel atoiStr9]
|
||||
call atoi
|
||||
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
|
||||
|
||||
;--- itoa()
|
||||
|
Reference in New Issue
Block a user