I came up with this code when I wanted to convert a decimal value to binary. When I do a SetDlgItemText with the buffer (I'm using a LOCAL one) the first (yes, the beginning of the string) eight characters disappear (output string is 24 bytes instead of 32). Is it something wrong with my algo?



dec2bin PROC USES edi number:DWORD, buffer:DWORD

mov edx,number
mov byte ptr[buffer+32],0 ;null terminate buffer
mov ecx,32

@@:
rcr edx,1
setc al
or al,30h
mov byte ptr [buffer+ecx-1],al
dec ecx
jnz @B

ret
dec2bin endp



Thanks.
Posted on 2003-03-01 16:25:29 by Delight
Well, the problem is that you overwrite the buffer address with the string, instead of the buffer itself. In this case, it's coincidentally right next to the string itself, only with a variable in between.
Posted on 2003-03-01 19:01:29 by Sephiroth3
Don't you want to have the line "mov <some register>, buffer" in there somewhere?
At the moment, I'm guessing you're messing with the stack, and it just so happens to work, by luck, rather than judgement, bar the side effect of loosing some of the bits.

One other thing, you can move the "dec ecx" above the "mov byte ptr" line, get rid of the -1 and it'll still work. The mov instruction doesn't affect the flags.

Mirno
Posted on 2003-03-01 19:05:14 by Mirno
Your algo looks OK (apart from Mirno's suggestion). The problem may be with your calling code and what you use to refer to your buffer.

(I was also wondering why you state "USES edi" in the PROC prolog. I can't see it used anywhere!)

Raymond
Posted on 2003-03-01 21:19:30 by Raymond
It is strange that the first 8 characters disappear.
If it whould be stack problem, then most likely either last
characters would disappear or first charaters would have
some garbage.
The only scenario I could imaging about disappearing the first characters -
is that pointer to buffer when dec2bin called and pointer to buffer
when SetDlgItemText differ from each other - one used with
SetDlgItem is more by 8.
Posted on 2003-03-01 23:34:14 by The Svin
Thanks for your help guys, I understand what I made wrong and have now corrected it so it works.



dec2bin PROC USES edi number:DWORD, buffer:DWORD

mov edx,number
mov edi,buffer
mov byte ptr[edi+32],0 ;null terminate buffer
mov ecx,32

@@:
rcr edx,1
setc al
or al,30h
dec ecx
mov byte ptr [edi+ecx],al
jnz @B

ret
dec2bin endp

Posted on 2003-03-02 02:39:01 by Delight
How about speedup tricks?



mov ecx,8
@@: mov eax,edx
and eax,0Fh
imul eax,204081h
and eax,01010101h
add eax,30303030h
shr edx,4
dec ecx
mov [edi+4*ecx],eax
jne @B
Posted on 2003-03-02 12:15:52 by Nexo
Nexo, what about an SSE2 version? :)
Posted on 2003-03-02 13:01:33 by bitRAKE
Yes, SSE2 have power PMULUDQ. I have some ideas. I will do it on my work tomorrow. A good pastime :)
Night...
Posted on 2003-03-02 14:20:10 by Nexo
A nice working day :)
SSE2 is very very fast.



dataseg
shift do 01020408102040800102040810204080h
b01 do 01010101010101010101010101010101h
b30 do 30303030303030303030303030303030h

codeseg
; eax-binary
; edi-string
bin2str:
movdqa xmm2,[shift]
bswap eax
movd xmm0,eax
punpcklbw xmm0,xmm0
punpcklbw xmm0,xmm0
movdqa xmm1,xmm0
punpcklbw xmm0,xmm0
punpckhbw xmm1,xmm1
pand xmm0,xmm2
pand xmm1,xmm2
pcmpeqb xmm0,xmm2
pcmpeqb xmm1,xmm2
pand xmm0,[b01]
pand xmm1,[b01]
por xmm0,[b30]
por xmm1,[b30]
movdqu [edi+00],xmm0
movdqu [edi+16],xmm1
mov [byte edi+32],0
ret


It is can be easy adapted for pure MMX.
Posted on 2003-03-03 09:23:14 by Nexo

Yes, SSE2 have power PMULUDQ. I have some ideas. I will do it on my work tomorrow. A good pastime :)
Night...
Good idea, Nexo - didn't even have to use PMULUDQ. :alright:
Posted on 2003-03-03 20:05:57 by bitRAKE