Hello :) This one is driving me nuts.. I have in a buffer the string "123" (it can be a changing number - but will always be less than 1000.) Now I need to know how much it is to initialize my loop. How do I get this value into ecx ( i mean 123d = 7Bh ) I've tried it myself into copying the value from right to left, substracting 30h from it, but then I have 01 02 03 written in my buffer and as the number could be "12" too at the beginning I simply can't take the first * 64h and the second * Ah + the third. Honestly... I'm clueless :confused: Anyone ever had this problem? Jimmy This message was edited by JimmyClif, on 3/21/2001 12:56:53 PM
Posted on 2001-03-21 11:52:00 by JimmyClif
Hi JimmyClif, For that, you should use the 'new' 'functions' like 'htodw' or the others. It is in the v6sp1 of Masm32.(look in the 'masmlib.hlp'): In the help file: Conversions atodw htodw dwtoa dw2hex dw2ah udw2str ustr2dw This message was edited by Vom-bonjour:-(), on 3/21/2001 1:40:58 PM
Posted on 2001-03-21 12:39:00 by Vom-bonjour:-()
Hello Vom-Bonjour :D Did you read my signature? ****D*mn**** Why does this happen to me all the time? Thanks again ;)
Posted on 2001-03-21 12:52:00 by JimmyClif
I have no problems converting...but then I've built that wheel over and over again. Set your "accumulator" register to 0, and then for each digit from left-to-right do this: accumulator = 10 * accumulator + convert2binary(digitchar) Change "10" to "16", modify "convert2binary" to handle A-F as digits, and you have a hexadecimal converter. Using "123", we get a = 0 ; 00h a = 10 * (0) + 1 = 1 ; 01h a = 10 * (1) + 2 = 12 ; 0ch a = 10 * (12) + 3 = 123 ; 7bh This message was edited by tank, on 3/21/2001 8:13:44 PM
Posted on 2001-03-21 19:11:00 by tank
My Idea for this is along the lines of what tank introduced, but his wil fail for 2 or 1 digit numbers unless checked for, as well i used shifts instead of multiplies for 10's and 100's:
``````
.data
szNum db "501",0

.code
lea eax, szNum
mov edx,
xor eax, eax        ; zero eax
mov ebx, edx        ; copy it
shl ebx, 11         ; 1 byte + 3 bits
jc Do_Hundred       ; 3 digits found
shl ebx, 8          ; check for 10's
jc Do_Tens
jmp Do_Ones

Do_Hundred:
mov ebx, edx        ; copy it
and ebx, 0000000Fh  ; get 100's
shl ebx, 2          ; 100 times X = (2^2 + 2^5 + 2^6) times X
add eax, ebx        ; Start a count for 100's
shl ebx, 3          ;
shl ebx, 1          ;
shr edx, 8

Do_Tens:
mov ebx, edx        ; copy it
and ebx, 0000000Fh  ; get 10's
shl ebx, 1          ; 10 times X = (2^1 + 2^3) times X
add eax, ebx        ; Start a count for 10's
shl ebx, 2          ;
shr edx, 8

Do_Ones:

and edx, 0000000Fh

``````
:cool: The average clocks, was from 13-17 depending on the number width. Its probably 2 or 3 clocks faster than this on a Pentium as Svin pointed out to me from an earlier post. I actually like this so much i decided to make a macro out of it, called A2DW_3, for Ascii -> DWORD, 3 digit. :D NaN This message was edited by NaN, on 3/21/2001 11:13:25 PM
Posted on 2001-03-21 21:48:00 by NaN
To NaN: If I get it right you are converting 3 bytes ASCII string representing dec value to DWORD? May you be interested in this I wrote? .data szNumber db '501',0 .code mov eax,dword ptr NUM ; U xor edx,edx ; pare 1 clock V AND eax,0F0F0Fh ;U xor ecx,ecx ; pare 1 clock V mov dl,ah ; - tens mov cl,al ; pare 1 clock V - figures lea edx, ;U edx*5 shr eax,16 ;V pare 1 clock al - hundreds add edx,edx ; U edx*2 lea eax, ;V pare 1 clock add edx,ecx ;U lea eax, ;V pare 1 clock shl eax,2 ;AGP 1 clock add eax,ecx ;1 clock ;value in eax now ---------------- 8 clocks
Posted on 2001-03-22 06:56:00 by The Svin
to Nan: Sorry - two instr need to be added ater first bswap eax shr eax,8
Posted on 2001-03-22 07:25:00 by The Svin
Svin, Thats very impressive. I keep forgeting the advantages of lea for mathematics (seeing it can provide shifting and adding at once). Im at school right now, so i can't copy and test your source, but as i have read it, there is a small error in the last line, it should 'add eax, edx' since you have already added the ones (ecx) to (edx) three lines above. None the less, it also has limitations of supporting numbers from 100 -> 999 in ASCII. The origion post indicated it must suport 0 -> 999, which is where my first 5 line of code checks for (and consequently adding some clocks).
``````
mov ebx, edx        ; copy it
shl ebx, 11         ; 1 byte + 3 bits
jc Do_Hundred       ; 3 digits found
shl ebx, 8          ; check for 10's
jc Do_Tens
jmp Do_Ones
``````
I take advantage of the fact every ascii number will have an upper nibble of '0011' so by shifting left by 3, if i have a carry i know if the number is 3 digits, 2 digits or one digit. However, i do see alot to be learned in your solution, i am interested in learning more about proper pairing of instructions to make efficient use of the pipe-line (which is what i assume your doing with the '1 clock pair' comments). Is there some simple rule of thumb for organizing your code for this?, or is it more complex and require finding a text? NaN
Posted on 2001-03-22 09:53:00 by NaN
I normally code the conversion in a loop that checks if the next character is a valid digit. This allows conversion of arbitrarily sized numbers (provided the result doesn't overflow). It even allows for lots of leading zeros. (As this was posted in General instead of Beginners, I assumed the inquirer was willing to figure that out. :D) This message was edited by tank, on 3/23/2001 2:08:35 AM
Posted on 2001-03-23 01:04:00 by tank
As this was posted in General instead of Beginners...
Maybe I should have posted this in Algos too? *g* Being honest... erm... actually.. I keep forgetting the masmlib :D ... (Now, Jimmy hides in the codewoods far from all those fingers pointing at him)
Posted on 2001-03-23 05:25:00 by JimmyClif