stoi:
push ebp
mov ebp, esp
mov esi, [ebp+8] ;*string
mov edi, 1 ;multiplier
mov ebx, esi
xor eax, eax
xor ecx, ecx
.getSize:
inc ecx
inc esi
cmp byte [esi], 0
jne .getSize
mov esi, ebx
.convertToInt:
mov ebx, [esi+ecx-1]
At this point, you're getting multiple bytes into ebx. You only want one (at a time).
movzx ebx, byte [esi + ecx - 1]
Will do it, or you could do the same thing with:
xor ebx, ebx ; make sure upper bytes are clear
mov bl, [esi + ecx - 1]
sub ebx, 0x30
imul ebx, edi
imul edi, dword 10
add eax, ebx
loop .convertToInt
mov esp, ebp
pop ebp
ret
When your debugger shows you the number 4, it has converted it to the ascii character '4' for you. Don't let that confuse you - you're on the right track!
There is a somewhat simpler way to do it... if you multiply "result so far" by 10 before adding in the "new digit" each time, you don't need to change the multiplier for each digit, and you can work through the string "frontwards", without even knowing how long it is!
get a character from the string
make sure it's a valid decimal digit character
if it's zero, we're done
if it's "something else"... programmer's choice
C just figures we're done for any non-digit...
you may want to do something for "invalid digit"...
subtract '0' to "convert" it to a number
multiply "result so far" by 10
add in the new digit
until done
This is something Herbert Kleebauer showed me. It was originally generated by a compiler(!). Uses "lea" twice to multiply result so far by 10 and add the "new digit"... converted to a number!
;--------------------
; this has the "special property"
; that it "returns" the invalid
; character in cl,
; and the next position in edx
atoi:
mov edx, [esp + 4] ; pointer to string
xor eax, eax ; clear "result"
.top:
movzx ecx, byte [edx]
inc edx
cmp ecx, byte '0'
jb .done
cmp ecx, byte '9'
ja .done
; we have a valid character - multiply
; result-so-far by 10, subtract '0'
; from the character to convert it to
; a number, and add it to result.
lea eax, [eax + eax * 4]
lea eax, [eax * 2 + ecx - '0']
jmp short .top
.done:
ret
;------------------------
I thought that was pretty cute!
Best,
Frank