Re: Konverzió!!!!
Andras Tantos
andras at tantosonline.com
Tue Sep 27 17:28:26 CEST 2005
> Khm.. nem szorozgatunk 8-cal meg kettovel, mert az bonyi.... matematikus
> varazslas... elb..od..
>
> Ha fix 3 helyiertek van, akkor egyszeruen a legmagasabbnal egy 16 bites
> osszeadassal hozzaadsz ciklusban annyiszor 100-at (064H) amellyi binarisod
> maradt a pozicion a 030H ascii levagasa utan...
> Aztan a kovetkezo pozicio mint szamlalo 0AH val ciklusban, aztan ha
> perverz vagy szinten ciklusban 1-et, de ezt mar magaban is hozza lehet
> adni...:-)
>
> Ennel eccerubb es eronthatatlanabb kodolas nemletezik...
> De elegansabb az bizonyara, csak az konnyebb elrontani...
> Es aprogramban mashol meg ezer helyen elronthatod, minek ezzel is szivatni
> magad.... en legalabbis nem szoktam...:-)
>
Hmm...
Megirtam mindkettot (igaz C-ben). Annyit valtoztattam, hogy nem fejtem ki a
ciklust minden egyes jegyre. Nos, remelem azt kodoltam le, amit gondoltal (a
Conv2 lenne az altalad javasolt megvalositas, illetve a Conv3 a tied, de
kulon leirva minden szamjegy konverzioja):
#include <stdio.h>
int Conv1(const char *aStr) {
int Num = 0;
while(*aStr != 0) {
Num = (Num << 3) + (Num << 1) + *aStr - '0';
++aStr;
}
return Num;
}
int Conv2(const char *aStr) {
int Num = 0;
const int CoefArray[] = {100,10,1};
const int *Coef = CoefArray;
while (*aStr != 0) {
for(int i=*aStr-'0';i>0;--i) {
Num += *Coef;
}
++aStr;
++Coef;
}
return Num;
}
int Conv3(const char *aStr) {
int Num = 0;
for(int i=aStr[0]-'0';i>0;--i) {
Num += 100;
}
for(int i=aStr[1]-'0';i>0;--i) {
Num += 10;
}
Num += aStr[2]-'0';
return Num;
}
void main() {
char *Str = "123";
printf("From %s to %d or %d or
%d\n",Str,Conv1(Str),Conv2(Str),Conv3(Str));
}
Nem tudom, kinek melyik a bonyolultabb, de nezzuk mit csinal a fordito
(VC++):
Conv1 PROC
mov edx, DWORD PTR _aStr$[esp-4]
mov cl, BYTE PTR [edx]
xor eax, eax
test cl, cl
je SHORT $LN1 at Conv1
npad 4
$LL2 at Conv1:
movsx ecx, cl
lea eax, DWORD PTR [eax+eax*4]
add edx, 1
lea eax, DWORD PTR [ecx+eax*2-48]
mov cl, BYTE PTR [edx]
test cl, cl
jne SHORT $LL2 at Conv1
$LN1 at Conv1:
ret 0
Conv1 ENDP
Conv2 PROC
sub esp, 12
mov edx, DWORD PTR _aStr$[esp+8]
mov cl, BYTE PTR [edx]
xor eax, eax
test cl, cl
push esi
mov DWORD PTR _CoefArray$[esp+16], 100
mov DWORD PTR _CoefArray$[esp+20], 10
mov DWORD PTR _CoefArray$[esp+24], 1
lea esi, DWORD PTR _CoefArray$[esp+16]
je SHORT $LN4 at Conv2
push edi
npad 3
$LL5 at Conv2:
movsx ecx, cl
sub ecx, 48
test ecx, ecx
jle SHORT $LN3 at Conv2
mov edi, DWORD PTR [esi]
imul edi, ecx
add eax, edi
$LN3 at Conv2:
mov cl, BYTE PTR [edx+1]
add edx, 1
add esi, 4
test cl, cl
jne SHORT $LL5 at Conv2
pop edi
$LN4 at Conv2:
pop esi
add esp, 12
ret 0
Conv2 ENDP
Conv3 PROC
mov edx, DWORD PTR _aStr$[esp-4]
movsx eax, BYTE PTR [edx]
sub eax, 48
xor ecx, ecx
test eax, eax
jle SHORT $LN6 at Conv3
imul eax, 100
mov ecx, eax
$LN6 at Conv3:
movsx eax, BYTE PTR [edx+1]
sub eax, 48
test eax, eax
jle SHORT $LN3 at Conv3
lea eax, DWORD PTR [eax+eax*4]
lea ecx, DWORD PTR [ecx+eax*2]
$LN3 at Conv3:
movsx edx, BYTE PTR [edx+2]
lea eax, DWORD PTR [edx+ecx-48]
ret 0
Conv3 ENDP
Hat, ugy tunik a fordito szerint is az elso az egyszerubb megoldas
(legalabbis utasitasok szama szerint). Az optimalizacot szido urak resze
ajanlom ezt a kis csemeget:
lea eax, DWORD PTR [eax+eax*4]
...
lea eax, DWORD PTR [ecx+eax*2-48]
Itt ugye eax = (eax+eax*4)*2+eax-'a', azaz eax = eax<<3+eax<<1+ecx-'a'
Es a harmadik megoldas is tartogat nemi erdekesseget: sehol sincs benne
ciklus! A fordito rajott, hogy az elso ciklus vegulis 100-al szoroz, ezert
helyettesitette egy imul-al, a masodik pedig 10-el, es ott az elobb emlitett
'lea' trukkot hasznalja. Szoval az ASM osszehasonlitas nem is teljesen fair,
hiszen a harmadik verzional a generalt kod meg csak nem is hasonlit arra,
amit 'kezzel irnal ASM-ban'.
Persze ez PIC-en nem megy, de 'shift left' ott is van, gondolom. Meg egy
megjegyzes:
Az elso megoldas akarhany szamjegyre mukodik, a masodik (es harmadik)
kizarolag 3-ra. Azaz egyre vagy kettore sem. Ez lehet, hogy problemat okoz!!
Udv,
Tantos Andras
More information about the Elektro
mailing list