Which would be the fastest procedure to convert ascii number to hex?
Posted on 2002-02-25 07:23:25 by DZA
There are some optimized procs in the MASM32 package...
Posted on 2002-02-25 14:56:19 by JCP
I know there are other ways to do this but for me, to do it a single calculation:


ASCII number 13 is composed of 31h and 33h subtracting 30h from both values will result to 1h and 3h or 1d and 3d. Starting from the LSD, we must create a variable n.

First Step: (n == 1)
3h * 10 ^ n - 1 = 3

- increment n

Second Step: (n == 2)
1h * 10 ^ n - 1 = 10

adding both makes it 13. Create a loop for this. I suggest you find the length of the string, start at the end of the string until you arrive at the first byte of the string, get a single byte then do the routine. Or find the length of the string make this value your n, Start at the first byte, increment your way until you hit 0h(Our string terminator) and decrement n, then do the calculations on each every byte.

not tested though, but I'm too tired to create an algo. Or better yet check out the MASM library(masm32.inc and masm32.lib)

Happy ASMing!!!
Posted on 2002-02-25 15:12:45 by stryker

This my simple example. Not best, but work :)

(Sorry some labels Turkish language)

Have nice day,

; Decimal string to hex integer - CYDONIA

carpan dd 00
basamak db 00
hxsay1 dd 00
hxsay2 dd 00

call GetDlgItemTextA, hwnd, say1, offset sayi1, 10
lea esi, sayi1
lea edi, hxsay1
call hexconvert
call GetDlgItemTextA, hwnd, say2, offset sayi2, 10
lea edi, hxsay2
lea esi, sayi2
call hexconvert


mov byte ptr [basamak],al
mov dword ptr [carpan],1
mov dword ptr [edi],0
xor ebx,ebx
mov bl,[basamak]
add esi,ebx
dec esi

xor eax,eax
xor ecx,ecx
mov al,[esi]
or al,al
jz bitti
sub al,30h
mov ecx,[carpan]
mov ebx,ecx
mul ecx
add dword ptr [edi],eax
xor eax,eax
mov al,0ah
xchg ebx,ecx
mul ecx
mov [carpan],eax
dec esi
dec byte ptr [basamak]
or byte ptr [basamak],0
jnz hex2decloop

Just added the formatting to make your code easier to read. hutch--

thanks :alright: - CYDONIA
Posted on 2002-02-25 18:40:40 by CYDONIA
ok, maybe I wasn't clear enough

i need something like this:
year db '2002', 0

lea esi, year ;... some pointer to the ascii
Call TheProcedure
; and should return in BX or whatever 2002d
Posted on 2002-02-26 09:44:59 by DZA
You can always copy the original string to a "buffer" and add a at the end of the string. Or you can always use atodw from hutch's masm32 library, after that you can then convert it back to ascii and add at the end of the string? How's that?
Posted on 2002-02-26 09:50:00 by stryker
LOL @ add a "d" to the string:)
actually, I was NOT looking for a procedure to do that, but I was just asking which would be the fastest -just read the first post- (the one in Masm package? I don't believe)
Posted on 2002-02-26 10:43:24 by DZA
Umm, I really don't know if I can satisy the question but here goes. You said something like ascii number to hex, my answer is convert it to decimal form. If you take a look at my example above, the value we were talking about is 13. If you place a number on a register E.G. mov eax, 13 the eax register will contain these values 0000000Dh now it might look it's hex but it's only the hex equivalent of decimal number 13, so we must change it to Hex String to actually see the hex value in the EAX register. Try searching the board for a procedure called ToBaseXToAscii, I'm sure this is what you want.

So here's a rundown:

ASCII "13" -> atodw -> EAX = 0000000Dh -> ToBaseXToAscii -> Hex String

But the thread title says: Ascii to Dec? Try searching the source code and algorithms section, I hope you'll find what your looking for.

Happy ASMing!!!
Posted on 2002-02-26 23:02:43 by stryker


; Convert decimal string into dword value ; return value in eax
;String equ [esp+4]
mov eax,[esp+4]
push esi
mov dl,[eax]
xor ecx,ecx
cmp dl,2Eh
mov esi,eax
sbb edx,edx
mov eax,ecx
adc esi,0
jmp @F
again: lea eax,[eax+4*eax]
inc esi
lea eax,[ecx+2*eax]
@@: mov cl,[esi]
sub cl,30h
jns again
add eax,edx
pop esi
xor eax,edx
retn 4
atodw endp
Posted on 2002-02-26 23:15:57 by The Svin
Wonderful algo, Svin. Does this run faster, for you?
again:	lea eax, [eax+4*eax]

inc esi
lea eax, [ecx+2*eax-30h]
@@: mov cl, [esi]
cmp [esi], 30h
jns again
...and newer processors:
again:	lea eax, [eax+4*eax]

inc esi
lea eax, [ecx+2*eax-30h]
@@: movzx ecx, BYTE PTR [esi] ; prevent stall
cmp BYTE PTR [esi], 30h
jns again
Edit: Here is another version that I would expect to perform well on modern processors:
	mov edx,[esp+4]

xor eax,eax
cmp BYTE PTR [edx],2Eh
sbb [esp+4],edx
adc edx,eax
jmp @F
lea eax,[eax+4*eax]
inc edx
lea eax,[ecx+2*eax-30h]
@@: movzx ecx, BYTE PTR [edx]
cmp BYTE PTR [edx],30h
jns again
add eax,[esp+4]

xor eax,[esp+4]
retn 4
I like not having to save a register, and the stack will be in the level 1 cache. :grin:
Posted on 2002-02-26 23:39:01 by bitRAKE
You need sub from cl, not just cmp it :)
There is some more to say, but I hope you'll find
it with a little bit more close look
Posted on 2002-02-27 00:57:56 by The Svin
Does not...
lea eax,[ecx+2*eax-30h]
...accomplish the same? I will go
test - to ensure I am not crazy. :)

Edit: Appears to work on my machine Svin. :grin:
Posted on 2002-02-27 10:00:44 by bitRAKE
You're right I missed -30h for the first time :)
You showed a whole bunch of interesting ideas, they might
be usefull but somewhere else, they don't make this particular proc faster. Though optional realizations always usefull to keep
in mind the options.
Posted on 2002-02-27 16:50:18 by The Svin
bitRAKE, the code specially for your computer ;) follows
; Input: esi-source string
; Output:eax-number
cmp , '-' + 1
sbb ebx, ebx
adc esi, 1
movzx eax,
sub eax, '0'
jmp @@ enA
@@ lp:
lea ecx,
imul eax, 100
lea edx,
add eax, edx
add esi, 2
@@ en:
movzx ecx,
sub ecx, '0'
jl @@ br
movzx edx,
sub edx, '0'
jge @@ lp
lea eax,
lea eax,
@@ br:
add eax, ebx
xor eax, ebx

Rise of speed rate on 57 % from Svin's version (string '123456789')
Posted on 2002-03-01 12:39:37 by Nexo
Thank you Nexo, I will examine.
Posted on 2002-03-01 12:51:43 by bitRAKE
i have a question

"imul eax,100" = eax=eax*100 or eax=eax^2*100 ?



EDIT: i understand that imul eax,100 =eax=eax*100

so can you do instead imul eax,100
lea eax, ;eax=eax*5
shl eax,2 eax=eax*5*4
lea eax, ; eax=eax*5*4*5
Posted on 2002-03-01 20:10:49 by eko
eko, that algo was talored for the Athlon by Nexo. Of course, that would be an alternative, but imul works well on Athlon, too. Or, rather that is what I am assuming he meant by his comments - for I have yet to test it. :)
Posted on 2002-03-01 23:10:58 by bitRAKE
eko, I have tested some combinations with usage lea, but all of them gave big stalls (about 5 clocks) because of dependence of registers. I solved a problem outgoing from maximum multisequencing scalings with usage a lot of the stream architecture of the processor.
Posted on 2002-03-02 02:49:54 by Nexo
Nexo, what assembler do you use?
movzx eax, [[b]b,[/b] esi-1]
Posted on 2002-05-30 13:56:53 by bitRAKE
I still think that the quickest way is:

MOV AL, "0" <----ASCII in AL
SUB AL, 30 ;Convert to dec number
And now use the DectoHex that comes in all math libs ;)

HAve a nice week-end all of you :)
Posted on 2002-05-31 13:18:35 by slop