A classic function revisited
; __________________________________________________________________________________
ALIGN 16
; *****************************************************************
; *** All the registers are saved except: RAX RCX RDX R8 and R9 ***
; *****************************************************************
; Registers used: RDI, RAX, RBX, RCX, RDX, R10 and R11
Atoi PROC USES RBX RDI R10 R11,__lpszNumericString:LPSTR PARMAREA = 4 * QWORD
mov rdi,rcx
xor eax,eax
xor edx,edx ; Set initial total to 0
xor ecx,ecx
mov r11d,10 ; No more than 10 characters: 123 456 789 012
mov r10b,'0' ; Stock bounds into registers
mov bl,'9'
ALIGN 16
Atoi_convert :
mov al,BYTE PTR [rdi] ; Get the current character
test al,al ; Check for \0
jz Atoi_done
cmp al,r10b ; Anything less than 0 is invalid
jge @F ; I try to use AL very often to reduce the code
jmp Atoi_error
ALIGN 16
@@:
cmp al,bl ; Anything greater than 9 is invalid
jle @F
jmp Atoi_error
ALIGN 16
@@ :
sub al,r10b ; Convert from ASCII to decimal
mov cl,dl
shl edx,3 ; * 8 ----> No multiplication
shl ecx,1 ; * 2
add edx,ecx ; Multiply total by 10
add edx,eax ; Add current digit to total
add edi,1 ; Get the address of the next character
sub r11d,1 ; SUB & ADD used rather than INC & DEC
jnz Atoi_convert
ALIGN 16
Atoi_error :
mov rax,-1 ; Return -1 on error in RAX
ALIGN 16
Atoi_done :
mov eax,edx ; CWD more effiscient?
ret ; Return total or error code
; __________________________________________________________________________________
Atoi ENDP
If the Input String has more than 10 chacaracters, the function stops.Maybe there is no ending '\0'
Here is another version from the Masm64 package :
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
atou_ex proc
; ------------------------------------------------
; Convert decimal string into UNSIGNED QWORD value
; ------------------------------------------------
; argument in RCX
xor r11, r11
movzx rax, BYTE PTR [rcx]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+1]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+2]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+3]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+4]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+5]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+6]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+7]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+8]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+9]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+10]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+11]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+12]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+13]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+14]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+15]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+16]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+17]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+18]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+19]
test rax, rax
jz quit
lea r11, [r11+r11*4]
lea r11, [rax+r11*2-48]
movzx rax, BYTE PTR [rcx+20]
test rax, rax
jnz out_of_range
quit:
lea rax, [r11] ; return value in EAX
or rcx, -1 ; non zero in RCX for success
ret
out_of_range:
xor rax, rax ; zero return value on error
xor rcx, rcx ; zero in ECX is out of range error
ret
atou_ex endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end
VORTEX, I should appreciate that you explain it in details
I have changed of keyboard this morning, now it has led every where and they exchanged 2 keys (END and DEL)! So excuse me if words are not well written. Made in China...
Hi Vortex,
MASM64?? Where to get this package? I thought MASM32 was all there was...
John Z
Hi John,
I think that there is a copyright on it. So you will not find it as a free compiler. Try to download windows SDK
I prefer POASM and you can use the debugger with it. The syntax is very close from MASM
Quote from: HellOfMice on December 19, 2024, 04:33:02 PM
Hi John,
I think that there is a copyright on it. So you will not find it as a free compiler. Try to download windows SDK
I prefer POASM and you can use the debugger with it. The syntax is very close from MASM
Thanks!
John Z
Hi John,
You can get the Masm64 SDK from this thread :
https://masm32.com/board/index.php?topic=10880.0
Hi Philippe,
OK, I will try later to post here the explanation of the source code.
Thank You Vortex, it seems too hard for me
Quote from: Vortex on December 19, 2024, 07:52:39 PM
Hi John,
You can get the Masm64 SDK from this thread :
https://masm32.com/board/index.php?topic=10880.0
Thanks very much Vortex!! This
might motivate me to take it up again....I'm certainly going to load and look.
John Z
I cannot install the VLSX file. I stopped the antivirus but no result the file crash. I open the file with 7zip and extracted the X64 folder
Quote from: HellOfMice on December 20, 2024, 08:50:40 AM
I cannot install the VLSX file..... I open the file with 7zip and extracted the X64 folder
A that packed file is just part of installation and update system, not something like msi.
It has been extracted with 7zip
And what you think, that i have missed ?
Just stay in in this actual topic about asm atoi ;)
In four days it is Christmas
for thank you for the work made in this forum
I made you this (see below)
It is a sad year, Pelle has gone. I like what he did and found him very strong.
I hope he has no personal problem and a good health.
I will wish the same thing for the next year.
When I look at the biathlon on TV I often think to you.
A+
Philippe
Hello,
With thanks to jj2007, member of the Masm Forum, you can try the new Masm64 package downloading also the Microsoft Masm 64-bit assembler :
QuoteMasm64 SDK installer: betatesters please
https://masm32.com/board/index.php?topic=12051.0
Direct link :
https://masm32.com/files/MASM64-SDKdev/Working/Installer/Masm64Sdk21set24.zip
I kow him, he is is a nice italian programmer
Hi Philippe,
Converting the atou_ex function from Masm64 to Poasm64 is very easy. The two versions are almost identical.
The method to convert a string to A number is handling correctly the Base-10 number system. To get the numerical value of a simple ASCII digit, one must extract 48 from this ASCII code. For example, the ASCII code of 5 is 53. 53-48=5
To shift each digit to the left, you multiply it by 10 :
lea r11, [r11+r11*4] ; r11=5*r11
lea r11, [rax+r11*2-48] ; r11=2*r11 + rax - 48
r11+r11*4 means multiplying r11 by 5. In the second line, after multiplying r11 by 2 , r11 becomes 10*r11 compared to the initial value of this register. The rest is easy, rax holds the ASCII digit and subtracting 48 from rax provides the numerical value.
The largest value of an unsigned 64-bit integer is 2^20 = 18446744073709551616. This means that a maxinum of 20 steps is necessary to convert correctly an ASCII string to integer.
Attached is a simple example, you can examine it with x64dbg to see how the algorithm works.
Hi Vortex
Thank you for your comments I learnt something:
Quotelea r11, [rax+r11*2-48] ; r11=2*r11 + rax - 48
I did not know this was possible!
Thank you professor and Happy, merry christmas.
Philippe
Surprising!
It is like this function only know to do one thing!
If you have others like this I take
Merci
Philippe
Hi Philippe,
The Masm32 and Masm64 packages are providing a lot of useful funcrions. You can download the installers and study the help files shipped with them.
Yes that's right, I already downloaded it but the functions I looked at where not as much interesting than the atou_ex. I am looking at its code, not finished since you sent the post.
A gift for my 65 years birthday.
I wanted to answer to your MS-DOS header message, but you did not let me the time to do it. I answer into this one.
I think I saw interesting things into CCleaner header.
I will write a small program for using atou_ex and seeing how it works under the debugger.
Very good and thanks again Vortex
Philippe