| STATYSTYKI |
Od 06.09.2000
|
Optymalizacja: 1024x768, IE5 |
|
| Pętle |
LOOP
Jest to podstawowa instrukcja realizująca pętle w assemblerze. Licznikiem tej pętli jest rejestr CX, a parametrem instrukcji LOOP jest etykieta pętli.
Szablon:
mov cx,rozmiar_petli
etykieta_petli:
;.....instrukcje petli
loop etykieta_petli
Instrukcja LOOP zmniejsza automatycznie rejestr CX o 1 i jeśli CX jest różne od zera,
to wykonuje skok do wskazanej jako parametr etykiety pętli.
Najdłużej wykona się pętla o rozmiarze 0 (mov cx,0), bo wtedy instrukcje_petli wykonają się 65536 razy.
Jest to spowodowane kolejnością wykonywania operacji przez LOOP. Najpierw odejmuje 1 od licznika (CX) i dopiero wtedy sprawdza, czy licznik jest różny od zera.
A więc jeśli rozmiar pętli nie jest jawnie określony, czyli jest wynikiem wcześniejszych operacji to w celu uniknięcia pętli zerowych możemy zastosować skok warunkowy jcx,
który skacze, gdy CX=0 (jcx omin_petle).
Należy uważać przy instrukcji LOOP także, aby nie zmieniać dowolnie zawartości rejestru CX w pętli, unikniemy wtedy np. zapętleń programu, czyli pętli nieskończonych.
Jeżeli już musimy zmienić wartość rejestru CX, to możemy posłużyć się tutaj stosem albo wprowadzić zmienną pomocniczą(lub inny rejestr),aby zapamiętać każdorazowo stan rejestru CX.
Przy pomocy instrukcji LOOP możemy także realizować pętle zagnieżdżone. Jeżeli chcemy wykorzystać do tego tylko rejestr CX to musimy się posłużyć się stosem lub zmiennymi pomocniczymi do zapamiętania stanu CX.
Przykład pętli w pętli:
mov cx, 50
petla_1:
push cx
mov cx,1000
petla_2:
;....instrukcje petli wewnetrznej
loop petla_2
;....instrukcje petli zewnetrznej
pop cx
loop petla_1
Analogicznie możemy realizować pętle bardziej zagnieżdżone. Licznik każdej pętli (ewentualnie poza najbardziej wewnętrzną) musimy zapamiętywać na stosie lub w zmiennej pomocniczej.
LOOPx
Pętle LOOP z przyrostkami są rozszerzeniem zwykłej pętli LOOP. Warunkiem ich wykonania nie jest jedynie zawartość rejestru CX, lecz także odpowiedni stan znacznika ZF(z.zera).Rodzaje pętli:
LOOPE, LOOPZ - obie instrukcje działają tak samo(można ich używać zamiennie): odejmują 1 od CX i jeśli CX jest różne od zera i znacznik ZF=1, to wykonują skok do etykiety pętli.
Instrukcje LOOPNE i LOOPNZ można np. wykorzystać do wyszukiwania niezerowych elementów tablicy. Należy tutaj zaznaczyć, że podczas wykonywania instrukcji pętli nie wolno nam dowolnie zmieniać zawrtość rejestru CX oraz znacznika ZF(niektóre użyte instrukcje zmieniają automatycznie jego wartość, np. INC).
LOOPE, LOOPZ - obie instrukcje działają tak samo(można ich używać zamiennie): odejmują od CX 1 i jeśli CX jest różne od zera i ZF=0, to wykonują skok do etykiety pętli.
Inne realizacje pętli
Czasmi, kiedy nie chcemy lub nie możemy wykorzystać rejestru CX jako licznika pętli lub instrukcji LOOP jako instrukcji sterującej pętlą to możemy wtedy zastosować zwykłe instrukcje warunkowe.
Czasem jest to nawet pętla szybsza niż z użyciem LOOP.Przykład pętli z użyciem rejestru SI:
mov si, 500 ;rozmiar petli
skok:
;....instrukcje petli
dec si ;zmniejsz si(licznik petli)
jnz skok ;jeśli si >0 to wykonaj skok petli pod etykiete skok
Należy podobnie jak w pętlach LOOP zadbać o zawrtość licznika pętli(SI).
Przykład pętli z użyciem zmiennej:
licznik dw 0 ;zmienna pomocnicza(licznik petli)
mov licznik,20 ;rozmiar petli
skok:
;....instrukcje petli
dec licznik ; zmniejsz licznik petli
jnz skok ;lesli licznik >0 to wykonaj skok pod etykiete skok
Krok pętli możemy zmniejszyć o dowolną (taką jaka nam jest aktualnie potrzebna) wartość, lecz wtedy zamiast skoku jnz musimy użyć skoku jns.
Jeżeli zależy nam na optymalizacji pod kątem szybkości wykonywania się instrukcji w pętli to możemy zawartość pętli 'rozwinąć' - umieszczamy w jednym ciągu te same instrukcje (zawartość pętli) powtórzone tyle razy ile wynosi maksymalny rozmiar pętli. Następnie zamiast wykonywać pętle skaczemy do odpowiedniego miejsca tego łańcucha instrukcji, tak aby do końca łańcucha zostało tyle 'zawartości pętli' jaki był jej rozmiar.
Potężną wadą 'rozwijania' pętli jest nieekonomiczne wykorzystanie pamięci. Może bowiem zdarzyć się że program taki zostanie rozbudowany o kilka tysięcy takich samych linni. Jednak różnica w szybkości działania jest widoczna.
<<
|
|