Assembly Language for Beginners

(nextflipdebug2) #1

3.10. STRING TO NUMBER CONVERSION (ATOI())


rt=rt*10 + (*s-'0');
s++;
};

return rt;
};


int main()
{
printf ("%d\n", my_atoi ("1234"));
printf ("%d\n", my_atoi ("1234567890"));
};


So what the algorithm does is just reading digits from left to right.


The zeroASCIIcharacter is subtracted from each digit.


The digits from “0” to “9” are consecutive in theASCIItable, so we do not even need to know the exact
value of the “0” character.


All we have to know is that “0” minus “0” is 0, “9” minus “0”’is 9 and so on.


Subtracting “0” from each character results in a number from 0 to 9 inclusive.


Any other character leads to an incorrect result, of course!


Each digit has to be added to the final result (in variable “rt”), but the final result is also multiplied by 10
at each digit.


In other words, the result is shifted left by one position in decimal form on each iteration.


The last digit is added, but there is no shift.


Optimizing MSVC 2013 x64


Listing 3.22: Optimizing MSVC 2013 x64

s$ = 8
my_atoi PROC
; load first character
movzx r8d, BYTE PTR [rcx]
; EAX is allocated for "rt" variable
; its 0 at start
xor eax, eax
; first character is zero-byte, i.e., string terminator?
; exit then.
test r8b, r8b
je SHORT $LN9@my_atoi
$LL2@my_atoi:
lea edx, DWORD PTR [rax+rax4]
; EDX=RAX+RAX
4=rt+rt4=rt5
movsx eax, r8b
; EAX=input character
; load next character to R8D
movzx r8d, BYTE PTR [rcx+1]
; shift pointer in RCX to the next character:
lea rcx, QWORD PTR [rcx+1]
lea eax, DWORD PTR [rax+rdx2]
; EAX=RAX+RDX
2=input character + rt52=input character + rt*10
; correct digit by subtracting 48 (0x30 or '0')
add eax, -48 ; ffffffffffffffd0H
; was the last character zero?
test r8b, r8b
; jump to loop begin, if not
jne SHORT $LL2@my_atoi
$LN9@my_atoi:
ret 0
my_atoi ENDP


Acharactercanbeloadedintwoplaces: thefirstcharacterandallsubsequentcharacters. Thisisarranged
so for loop regrouping.

Free download pdf