3











PTiK - Porady, Tipsy i Kursy
defaultStatus="Assembler";










Zaczynamy
na dobre (3)





"Operacje
matematyczne"



Po tym wszystkim, co już dotychczas
zrobiliśmy, to, czym zajmiemy się teraz jest proste jak ... się za chwilę
przekonasz.
Nie zwlekając więc ni chwili przystąpmy do rzeczy.

INC i DEC

Są to instrukcje analogiczne jak w Pascalu, z małym
wszakże wyjątkiem, ale o tym za moment - powodują zwiększenie lub
zmniejszenie jakiejś wartości.

Składnia:

INC A
DEC A

No więc cała różnica polega na tym, że
- jak widać - nie ma tu drugiego parametru, który określałby o ile ma być
zwiększona lub zmniejszona dana wartość. Parametru tego nie ma, gdyż zawsze
jest ona zmniejszana/zwiększana o 1 - słownie jeden.
Rozwiewając więc resztki wątpliwości wszystkich, którzy takie wątpliwości
jeszcze zachowali powiem, że INC zwiększa a DEC
zmniejsza daną wartość...
Przykładowo, jeśli w AX mamy wartość 03H,
to wykonanie instrukcji

INC AX - zwiększy
AX o 1 - AX będzie się równać 04H.

Jeśli więc w tym stanie rzeczy wykonamy instrukcję

DEC AX - to wartość
AX zostanie zmniejszona o 1 - z wartości 04H na 03H.

 
Dodawanie i odejmowanie


Do tych operacji można oczywiście używać DEC i INC,
ale - oczywiście - byłoby prawie nie do pomyślenia, że Assembler nie udostępnia
żadnej instrukcji umożliwiającej wykonanie powyższych działań "za
jednym zamachem" tzn. bez konieczności zmieniania wartości o 1.
Instrukcje, które umożliwiają wykonanie dodawania lub odejmowania to ADD
(dodaj) i SUB (substract
- odejmij).

Składnia:

ADD A, B
SUB A, B

Wykonanie powyższych instrukcji powoduje
dodanie (lub odjęcie w przypadku SUB) wartości A i B i wrzucenie wyniku do A -
np.: Jeśli AX=5 i wykonamy ADD AX, 08H
- to procesor najpierw doda 5+8 a następnie wrzuci wynik do aX - po wykonaniu
powyższego polecenia AX będzie równe 13 (dziesiętnie) czyli 0DH.
Analogicznie - wykonanie w tym stanie rzeczy instrukcji SUB
AX,3 spowoduje odjęcie trójki od aktualnej wartości AX i
wrzucenie wyniku do AX (13 - 3 =10) - AX=10D czyli 0AH.
 
Mnożenie
Tutaj sprawa nie jest już tak prosta jak w przypadku
dodawania i odejmowania, dlatego też mnożenie i dzielenie zostaną omówione
oddzielnie.
Do mnożenia służy w Assemblerze instrukcja MUL
(multiply - mnóż).

Składnia:

MUL A

Niewątpliwie wymaga to pewnych wyjaśnień
- wyjaśniam więc: MUL powoduje pomnożenie wartości A razy
zawartość rejestru AX, lecz sprawa wygląda nieco inaczej, gdy A jest wartością
typu word (słowo - 2 bajty) lub byte (bajt).
Gdy więc A jest to 1 bajt, wówczas wykonywane jest mnożenie a*AL (przypomnę,
że AL jest to młodszy bajt rejestru AX) i wynik mnożenia zostaje wrzucany do
AX. Załóżmy, że AL=2 a BL=3 - wówczas wykonanie instrukcji
MUL BL -
powoduje wymnożenie 2*3 i wrzucenie wyniku do AX - AX=6.
Jeśli jednak A jest wartością dwubajtową,
to A jest mnożone razy AX a wynik zostaje wrzucany do rejestrów DX:AX tzn. DX
zawiera 2 starsze a AX młodsze bajty - np:. Jeśli AX = 0FFFFH (65535) i BX=0FFFFH
(65535 również), to wykonanie
MUL BX wymnoży
BX*AX a wynik (w tym przypadku czterobajtowy 0FFFFFFFFH
czyli 4294836225D) znajdzie się w DX (2 bajty)
i AX (również 2 bajty).
 
Dzielenie
Instrukcją dzielącą jest w Assemblerze
DIV
(divide - dziel).

Składnia:

DIV A

Tutaj znowu - jak w przypadku mnożenia - ma znaczenie
czy A jest bajtem (np. BH, BL), czy słowem (NP. BX).
Jeśli A jest bajtem, AX jest dzielony przez A; iloraz
zostaje wrzucony do AL, reszta do AH.
Jeśli więc AL zawiera 10D (0AH), BH=3, to po
DIV BH
AL=3, AH=1 - bo oczywiście 10/3 =3 i reszty 1.
Gdy A jest słowem (2 bajty), DX:AX zostaje podzielony
przez A; po dzieleniu AX zawiera iloraz a DX resztę z dzielenia - np.:
Jeśli - posługując się analogicznym przykładem co przy mnożeniu - ustawimy
DX=0FFFFH, AX=0FFFFH (dzielna =0FFFFFFFFH) i BX=0FFFFH (dzielnik), to
DIV BX
ustawi AX=0FFFFH (iloraz) DX=0000H (reszta).
 
No - dość tego sporo:)) - przydałby się
jakiś ilustrujący wszystko przykładzik, ale - obawiam się, że wszyscy, którzy
na to liczą - zawiodą się; nie mam żadnego sensownego pomysłu a bezsensowne
przykłady umieszczałem na bieżąco przy omawianiu każdego działania.
Nie ma powodów do obaw - najwyższy już czas napisać coś większego z użyciem
wszystkich poznanych instrukcji - to następnym razem
"LOOP,
LOOPE, LOOPZ, LOOPNE, LOOPNZ"
 
Jak pisałem poprzednio, przy naszych obecnych umiejętnościach
spokojnie można zrobić pętlę "for .. to ..." - choćby tak, jak to
demonstruje ten przykład.
Oczywiście - pętla działa co można bez trudu
stwierdzić - poprawnie, lecz to jest pretekstem do wprowadzenia właśnie
instrukcji LOOP.

Składnia:
LOOP ETYKIETA

Tu warto od razu wyjaśnić, że loop
- z angielskiego oczywiście - znaczy "pętla".
No ale co właściwie robi LOOP? Mówiąc krótko -
zaledwie dwie rzeczy: Po pierwsze - zmniejsza wartość CX
o jeden (DEC CX), po drugie - jeśli CX jest większe 0
powoduje bezwarunkowy przeskok do "ETYKIETA".
Jeśli chcielibyśmy powiedzieć to językiem
procesora - LOOP ETYKIETA jest skrutem poniższych komend:

DEC CX
CMP CX,0
JNE ETYKIETA


Nie trzeba tu filozofa by stwierdzić, że LOOP umożliwia
tylko budowę pętli typu "downto" czy - jak w basicu - "step
-1" - a po ludzku pętli, w której licznik maleje a nie rośnie.
Oczywiście jest to prawda, ale prawdą jest też, że nie warto się męczyć
wykonywaniem powyżej pokazanej pętli, gdy można to
rozwiązać LOOP'em.
Ponieważ postraszyłem w nagłówku pół tuzinem instrukcji, najwyższy czas
zakończyć ten przydługi opis LOOP - za podsumowanie musi wystarczyć przykładowy
programik.
 
 
LOOPE/LOPZ,
LOOPNE/LOOPNZ


Instrukcje LOOP?? mają - jak nie
trudno się domyśleć - coś wspólnego z instrukcją LOOP.
Tym czymś jest choćby użycie.

Składnia:
LOOPE ETYKIETA
LOOPZ ETYKIETA
LOOPNE ETYKIETA
LOOPNZ ETYKIETA


Nie trudno się też domyśleć, że LOOP??
dotyczą w jakiś sposób instrukcji skoku warunkowego...
Kończąc więc domysły wyjaśniam, że działanie instrukcji LOOP**
jest następujące:

Zmniejszyć CX o jeden (DEC CX - tak jak przy
LOOP)
Jeśli CX>0 wykonać skok warunkowy do "ETYKIETA"
w zależności od typu instrukcji: LOOPE - JE, LOOPNE - JNE, LOOPZ -
JZ, LOOPNZ - JNZ.

Jeśli CX=0, lub nie spełniono warunku skoku
warunkowego, zakończyć pętlę.

A po jakie licho jest to wszystko aż tak dokładnie
zamotane? - jedną z przyczyn jest oczywiście - wyjście na przeciw programiście...
teraz ma on możliwość wykonania działania w pętli, które nie tylko będzie
uzależnione od wartości CX, ale nawet może on przeprowadzić
porówn anie dwóch innych wartości (np. CMP AX,BX) i również
na tej podstawie wykonać pętlę lub jej nie wykonać... np. procedurka
upewniająca się - zadająca użytkownikowi ważne pytanie, które musi on
potwierdzić 3 razy np. "czy formatować dysk" - mogłaby
wyglądać tak jak to przedstawia niniejszy program.
Mam nadzieję, że po jego analizie nie będziesz mieć już żadnych wątpliwości,
ale oczywiście - gdybyś jednak miał mieć - czekam na pytania.
 




Wyszukiwarka

Podobne podstrony:
edukomp kl 3?u przy naprawcze
v3
page36
3 Goniometricke funkce
page3
baza 3
3? EXAM LANGUAGE ELEMENTSfor students
11id?3

więcej podobnych podstron