1) atoi: signed+unsigned overflow checks (JC,JO) 2) correct values for MIN_INTxx constants

This commit is contained in:
2025-08-03 13:25:47 +02:00
parent d386aa5744
commit 02580e9b0b
3 changed files with 49 additions and 13 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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()