@sander,
moja osnovna zamerka AVR-u nije brzina, vec potrosnja flash-a.
Inace, AVR je sampion u brzini ako je dovoljno 32 bajta za sve varijable programa.
Indirektno adresiranje moze biti sa ofsetom. Ako imas neki niz, od bajtova, sa adresom prvog elementa niza na adresi Niz, i zelis 20 element, onda ti treba:
ldi Ry, Niz.0; // visi bajt adrese niza, Ry i Ry+1 je Ry dvobajtni registar
ldi Ry+1, Niz.1; // nizi bajt vadrese niza
ldd Rn,Y+20; // gde je ofset = 20; 0 <= ofset <= 63
za ovo je potrebno 3 ciklusa.
Ako se kopiraju dva niza iste duzine:
ldi Ry, Niz1.0;
ldi Ry+1,Niz1.1;
ldi Rz, Niz2.0;
ldi Rz+1,Niz2.1;
ldi R16,SizeOf(Niz1); //trosi 10 bajta programa
Ponovo: //petlja trosi 7 ciklusa i 8 bajta programa
ld R17,Rz+;
st Y+,R17;
dec R16
brne Ponovo;
Ili ako oba niza pocinju na adresama manjim od 64:
ldi Ry,SizeOf(Niz1);
eor Ry+1,Ry+1; //Ry+1 je nula; trosi 4 bajta programa
Ponovo: //petlja trosi 7 ciklusa i 8 bajta programa
ldd R17,Y+Niz2-1;
std Y+Niz1-1,R17;
dec R17;
brne Ponovo;
Takodje je moguce prebaciti stek pointer u neki od indeksnih registara i tako praviti dinamicke lokalne varijable na steku. Ovo je vrlo zgodna stvar.
No, ostaje moja primedba da AVR trosi mnog flash-a, i pri tome ima mali ofset kod indirektnog indeksnog adresiranja.
Primera radi evo kako izgleda kopiranje nizova kod MC9S08.
Izvorni kod
Code:
ldhx SizeOf(Niz1);
repeat
ldaa x[Niz1-1];
staa x[Niz2-1];
until decr(IndX) =0;
i prevod:
Code:
$fa04 : $450064 ldhx $0064
$fa07 : $e654 ldaa x[$54]
$fa09 : $e7b8 staa x[$b8]
$fa0b : $5bfa dbnzx $fa07
Ovaj kod trosi 9 bajta memorije, a petlja traje 9 ciklusa. Ako su nizovi proizvoljno u memoriji, onda ce duzina koda biti 11 bajtova a trajanje petlje 11 ciklusa. Ovaj kod vazi za bilo gde smestene nizove (cak jedan moze biti i u flash-u a drugi bilo gde u RAM-u). Jedino ogranicenje je da je duzina niza manja od 257 bajtova, inace bi kod morao biti malo modifikovan. Obzirom na strukturu MC9S08 i takt CPU-a koji iznosu 50ns, trajanje petlje je 450ns odnosno 550ns.
Ako uzmemo u obzir da je malo verovatno da oba niza kod AVR-a pocnu na adresama manjim od 63, onda je prvi primer AVR-a uporediv sa primerom za MC9S08. Proizilazi:
AVR: 18 bajtova i trajanje petlje 7 ciklusa (700ns)
MC9S08: 11 bajtova i trajanje petlje 11 ciklusa (550ns)
U odnosu na AVR, sa MC9S08 se stedi 38.9% u duzini koda i 21.4% u trajanju petlje.
Ovi odnosi nisu presudni, oni to postaju kada je faktor odnosa 2:1 ili gori. Postoje mesta u programu gde AVR postize bolji rezultat pa se moze govoriti samo o razlikama u nijansama.
Voleo bih kada bi neko napravio slicnu analizu za PIC.
Pozdrav.