CodeLan
Administrator
Dołączył: 03 Lis 2006
Posty: 171
Przeczytał: 0 tematów
Pomógł: 3 razy Ostrzeżeń: 0/5 Skąd: Z pod skrzydeł Google.pl
|
Wysłany: Nie 7:35, 17 Cze 2007 Temat postu: Skok warunkowy CMP i JMP |
|
|
Rzecz, którą za chwilę omówię jest prawie tak samo a może nawet bardziej ważna i przydatna jak omawiane już przerwania. Dotychczas ani razu nie mówiliśmy o instrukcjach warunkowych (if .. then) ani o sposobie porównywania dwóch wartości.
Do porównania dwóch wartości służy instrukcja CMP (compare - porównaj), której składnia jest następująca:
CMP A, B
A i B to dwie dowolne wartości, które porównujemy. Wykonanie instrukcji CMP powoduje ustawienie odpowiednich flag procesora (OF, SF, ZF), a to właśnie na tej podstawie są wykonywane instrukcje skoku, o których za chwilę - tematu które flagi są kiedy ustawiane i dlaczego tak a nie inaczej - nie chciałbym na razie zgłębiać bo może to tylko zamieszać i nie wnieść nic do sprawy...
Na etapie początkowym nauki assemblera wystarczy wiedzieć, że jeśli chcemy wykonać skok warunkowy ("If a>4 then" itp.) to najpierw wykonujemy instrukcję CMP A,4 a następnie jedną z poniższych...
Składnia instrukcji J**:
J** etykieta
"Etykieta" to oczywiście (tak jak w przypadku JMP, CALL) nazwa etykiety, do której program przeskoczy jeśli... No właśnie.
Przydatniejszych instrukcji J** jest kilka, ale są one nazwane wg pewnych reguł, których znajomość może zaoszczędzić sporo wkuwania więc w efekcie "nie taki diabeł straszny".
Pierwszą literę tych instrukcji stanowi zawsze J (jump if - skok jeśli), później może wystąpić N (not - nie) a na końcu A (above - ponad), lub E (equal - równe), lub B (below - poniżej).
Weźmy na przykład równość:
"J"+"E" czyli JE. W ten sposób możemy też zapisać nie-równość pisząc JNE... i tak dalej.
Jednej rzeczy należy się jednak nauczyć - jak już miałeś okazję zauważyć z tym assemblerem to tak nie zawsze i nie do końca "po ludzku" bywa, więc jeśli mielibyśmy instrukcje:
CMP A,B
JA et_wieksze
to ktoś mógłby zapytać, czy skok nastąpi jeśli A > B, czy jeśli B > A? Ktoś inny sprawdziłby to doświadczalnie, ale ja - z góry wyjaśniam. Tu akurat jest normalnie tzn. w powyższym przykładzie instrukcja JA wykona skok jeśli A > B - pisząc dla wyobraźni - A above B.
Myślę, że to w miarę bezboleśnie wyjaśniłem - Jak zapisać >=?
W assemblerze istnieje instrukcja JAE (Above or Equal), której oczywiście można używać (istnieje też JBE (below or equal)) - nie są to jednak instrukcje "pierwszej potrzeby" zwłaszcza, gdy ktoś nie chce się zbyt wiele uczyć (a ktoś chce? )), bo tak "na chłopski rozum" sprawa jest prosta:
Większe lub równe znaczy tyle samo co "nie mniejsze" a więc - JNB... I mamy to samo przy użyciu naszego pierwotnego szablonu bez żadnych JAE....
Przeglądając zestaw instrukcji przerwania 21H można natrafić (w opisie np. otwierania pliku) na zapis, że funkcja zwraca:
CF = 0 - wykonano bez błędów,
CF = 1 - wystąpił błąd (nr błędu jest w AX).
W praktyce więc chodzi o to, żeby sprawdzić czy dana flaga jest czy nie jest aktywna... a pisałem wcześniej, że właśnie J** bazuje na flagach czym się nie należy przejmować.
Jeśli więc porównujemy dwie wartości, to istotnie nie ma to znaczenia, ale jeśli interesuje nas stan jakiejś konkretnej flagi, to istnieje kilka użytecznych instrukcji J** przeznaczonych właśnie do tego. Są to:
JC - skok, gdy CF = 1;
JO - skok, gdy OF = 1;
JP - skok, gdy PF = 1;
JS - skok, gdy SF = 1;
JZ - skok, gdy ZF = 1;
Również tutaj stosuje się nieśmiertelna zasada not, czyli można stosować zapis np. JNC, który oznacza, że CF nie jest ustawiona - CF = 0; tyczy się to oczywiście pozostałych flag także (JNO, JNP, JNS i JNZ).
Wielokrotnie pisałem powyżej, że jest wiele... że się nie ma co przejmować... i wogóle tak, że spokojnie możnaby mi zarzucić herezję i nierzetelność.
Przewidując możliwość takiej sytuacji a jednocześnie chcąc uniknąć zawiłego i pokrętnego tłumaczenia, przygotowałem (dla zapaleńców choć i "leniwym" lektura nie zaszkodzi) pełny (mam nadzieję) zestaw instrukcji J**, który jednak (zastrzegam i ostrzegam) pochodzi z książki - większości tych instrukcji wogóle nie używałem i nie zamierzam:)).
Post został pochwalony 0 razy
|
|