3.10. STRING TO NUMBER CONVERSION (ATOI())
; ESI=0 here if there was no minus sign and 1 if it was
lea eax, [rdx-48]
; any character other than digit will result in unsigned number greater than 9 after ⤦
Çsubtraction
; so if it is not digit, jump to L4, where error will be reported:
cmp al, 9
ja .L4
xor eax, eax
jmp .L6
.L7:
lea ecx, [rdx-48]
cmp cl, 9
ja .L4
.L6:
lea eax, [rax+rax4]
add rdi, 1
lea eax, [rdx-48+rax2]
movsx edx, BYTE PTR [rdi]
test dl, dl
jne .L7
; if there was no minus sign, skip NEG instruction
; if it was, execute it.
test esi, esi
je .L18
neg eax
.L18:
add rsp, 8
ret
.L22:
movsx edx, BYTE PTR [rdi+1]
lea rax, [rdi+1]
test dl, dl
je .L20
mov rdi, rax
mov esi, 1
jmp .L10
.L20:
xor eax, eax
jmp .L18
.L4:
; report error. character is in EDX
mov edi, 1
mov esi, OFFSET FLAT:.LC0 ; "Error! Unexpected char: '%c'\n"
xor eax, eax
call __printf_chk
xor edi, edi
call exit
If the “minus” sign has been encountered at the string start, theNEGinstruction is to be executed at the
end. It just negates the number.
There is one more thing that needs mentioning.
How would a common programmer check if the character is not a digit? Just how we have it in the source
code:
if (s<'0' || s>'9')
...
There are two comparison operations.
What is interesting is that we can replace both operations by single one: just subtract “0” from character
value,
treat result as unsigned value (this is important) and check if it’s greater than 9.
For example, let’s say that the user input contains the dot character (“.”) which hasASCIIcode 46.
46 −48 =− 2 if we treat the result as a signed number.
Indeed, the dot character is located two places earlier than the “0” character in theASCIItable. But it is
0xFFFFFFFE(4294967294) if we treat the result as an unsigned value, and that’s definitely bigger than 9!