1. Operacje logiczne OR Operacje logiczne są operacjami działającymi na poszczególnych bitach, dzięki czemu można je całkowicie opisać przedstawiając jak oddziałują ze sobą dwa bity. Takie operacje logiczne przedstawia się najczęściej w postaci tabeli. A B A OR B 0 0 0 1 0 1 0 1 1 1 1 1 Operacja OR działa w ten sposób, że jeżeli bit A lub B ma wartość jeden to wynik też ma wartość 1 w przeciwnym wypadku wynik wynosi 0. Przykładowy wynik operacji OR na dwóch bajtach: bin hex dec A 00000011b 03h 3 B 00011001b 19h 25 A OR B 00011011b 1Bh 27 Operacja OR nazywana jest sumą logiczną, jednak może to być trochę mylne, ponieważ niewiele ma ona wspólnego z tym, czego uczyliśmy się o dodawaniu w szkole podstawowej. W asemblerze operacja ta służy przede wszystkim do ustawiania określonego bitu na wartość 1. Przykładowo mamy pewien rejestr o nazwie AL i chcemy ustawić jego trzeci bit na wartość 1 niezależnie od tego jaką on ma wartość obecnie. Wykonamy to po przez operację OR na rejestrze AL z liczbą która ma ustawiony trzeci bit czyli 02h. AL OR 02h, w wyniku niezależnie od tego jaką wartość miał rejestr AL będzie on miał trzeci bit ustawiony.: bin AL 01110100b B AL OR B 00000010b 01110110b
AND A B A AND B 0 0 0 1 0 0 0 1 0 1 1 1 Operacja AND da w wyniku wartość 0 tylko wtedy gdy bit A lub B miał wartość 0. Przykład: bin hex dec A 00000011b 03h 3 B 00011001b 19h 25 A AND B 00000001b 01h 1 Operacja AND nazywana jest iloczynem logicznym i właściwie można ją traktować podobnie jak zwykłe mnożenie bitowe. W asemblerze bardzo często stosuje się tą operacje do zerowania określonego bitu. Przykładowo chcąc wyzerować bit czwarty rejestru AL należy wykonać na nim operację AND z liczbą F7h. Liczba F7h ma wyzerowany bit czwarty, ale pozostałe bity ma ustawione. To pozwala zachować poprzednią wartość tych bitów. bin AL 01111000b B AL AND B 11110111b 01110000b
NOT A NOT A 0 1 1 0 Operacja NOT działa na tylko jednym argumencie. W wyniku daje liczbę o wartościach bitowych przeciwnych do wartości argumentu operacji. Przykład: bin hex dec A 00011001b 19h 3 NOT A 11100110b E6h 230 XOR A B A XOR B 0 0 0 1 0 1 0 1 1 1 1 0 Operacja XOR (exclusive OR) jest to operacja OR z pewną różnicą w stosunku do działania na obu ustawionych bitach. Operacja ta daje w wyniku 1 jeżeli oba bity miały różną wartość, a jeżeli miały taką samą wartość to wynik będzie wynosił 0. Operację tą też można tłumaczyć jako sumę modulo 2. Operacja modulo nie jest instrukcją procesora, a jedynie funkcją matematyczną, którą definiujemy jako zwracającą resztę z dzielenia pewnej liczby przez drugą liczbę. X mod Y oznacza w wyniku resztę z dzielenia liczby X przez liczbę Y. Tak więc można zapisać operacje logiczną A XOR B w postaci matematycznej jako (A+B) mod 2 (przypominam, że jest to operacja działająca na poszczególne bity). Ta definicja operacji XOR może być trudna do zrozumienia ze względu na swój matematyczny charakter.
W asemblerze często będziemy stosowali operację XOR do zerowania zawartości rejestrów po przez operację A XOR A, która zawsze w wyniku daje wartość 0. Dodatkowo operację tą będziemy również stosować do odwracania wartości określonego bitu. Przykładowo chcąc odwrócić wartości bitów pierwszego i ostatniego pewnego rejestru wykonamy operację XOR z następującym argumentem: bin hex dec A 00011001b 03h 3 B 10000001b 19h 25 A XOR B 10011000b 98h 152 Tak więc jako podsumowanie operacji logicznych stosowanych w asemblerze podam je w tabeli z krótkim opisem. Należy pamiętać, że operacje logiczne działają na odpowiadających sobie bitach obu argumentów. Operacja Opis zastosowania OR Ustawia określone bity AND Zeruje określone bity NOT Odwraca bity w argumencie XOR Odwraca wartości określonych bitów Przesunięcie bitowe w lewo (ang. shift left) Jest to operacja dwuargumentowa. Zapisywana jest z reguły jako: a shl b Operacja polega na przesunięciu a o b bitów w lewo. Przy czym bity pojawiające się z prawej strony (uzupełniające przesunięcie) są ustawiane na 0. Operacja ta jest równoważna mnożeniu przez 2.
Przesunięcie o 1 bit to przemnożenie a przez 2, przesunięcie o 2 bity to dwukrotne pomnożenie a przez 2, itd. PRZYKŁAD: 0101 shl 3 = 0101000 Przesunięcie bitowe w prawo (ang. shift right) Jest to operacja dwuargumentowa. Zapisywana jest z reguły jako: a shr b Operacja polega na przesunięciu a o b bitów w prawo. Operacja ta jest równoważna dzieleniu całkowitemu przez 2. Przesunięcie o 1 bit to podzielenie a przez 2, przesunięcie o 2 bity to dwukrotne podzielenie a przez 2, itd. PRZYKŁAD: 010110 shr 3 = 010 Obrót bitowy w prawo (ROR) Funkcja ROR czyli obrót w prawo przesuwa wartość pojedynczych komórek w prawo przy czym wartość ostatniej komórki ( wychodząca poza zakres ) jest przepisywana jest do komórki pierwszej. Rysunek poniżej ilustruje działanie funkcji. Obrót bitowy w lewo (ROL) Funkcja ROL czyli obrót w lewo przesuwa wartość pojedynczych komórek w lewo przy czym wartość ostatniej komórki ( wychodząca poza zakres ) jest przepisywana do komórki pierwszej. Rysunek poniżej ilustruje dzialanie funkcji.
2. Operacje arytmetyczne Dodawanie binarne Do wykonywania dodawania niezbędna jest znajomość tabliczki dodawania, czyli wyników sumowania każdej cyfry z każdą inną. W systemie binarnym mamy tylko dwie cyfry 0 i 1, zatem tabliczka dodawania jest niezwykle prosta i składa się tylko z 4 pozycji: 0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 10 Przykład: 1111001 + 10010 Zsumować liczby binarne 1111001 (2) oraz 10010 (2). 1. Sumowane liczby zapisujemy jedna pod drugą tak, aby w kolejnych kolumnach znalazły się cyfry stojące na pozycjach o tych samych wagach (identycznie postępujemy w systemie dziesiętnym zapisując liczby w słupkach przed sumowaniem): 1111001 + 10010 1011 2. Sumowanie rozpoczynamy od ostatniej kolumny. Sumujemy cyfry w kolumnie zgodnie z podaną tabelką zapisując wynik pod kreską: 1 1 1 11 0 0 1 + 10 0 1 0 01 0 1 1 3. Jeśli wynik sumowania jest dwucyfrowy (1 + 1 = 10), to pod kreską zapisujemy tylko ostatnią cyfrę 0, a 1 przechodzi do następnej kolumny - dodamy ją do wyniku sumowania cyfr w następnej kolumnie. Jest to tzw. przeniesienie (ang. carry). Przeniesienie zaznaczyliśmy na czerwono: 4. Jeśli w krótszej liczbie zabrakło cyfr, to dopisujemy zera. Pamiętajmy o przeniesieniach.
111 1 1 11 0 0 1 + 0 0 10 0 1 0 0 0 01 0 1 1 111 0 1 11 1 0 0 1 + 0 0 01 0 0 1 0 1 0 00 1 0 1 1 5. Dodaliśmy wszystkie cyfry, ale przeniesienie wciąż wynosi 1. Zatem dopisujemy je do otrzymanego wyniku (możemy potraktować pustą kolumnę tak, jakby zawierała cyfry 0 i do wyniku sumowania dodać przeniesienie). 1111001 (2) +10010 (2) =10001011 (2) (121 + 18 = 139) Oto kilka dalszych przykładów: 1111111 0 1 11 1 1 1 1 + 0 0 00 0 0 0 1 1 0 00 0 0 0 0 1111111 0 1 1 11 1 11 + 0 0 0 00 1 01 1 0 0 00 1 00 1111 10 1 11 1 10 + 00 0 01 1 00 11 0 01 0 10 Odejmowanie binarne Przy odejmowaniu korzystamy z tabliczki odejmowania, która w systemie binarnym jest bardzo prosta: 0-0 = 0 0-1 = 1 i pożyczka do następnej pozycji 1-0 = 1 1-1 = 0 Odejmując 0-1 otrzymujemy wynik 1 i pożyczkę (ang. borrow) do następnej pozycji. Pożyczka oznacza konieczność odjęcia 1 od wyniku odejmowania cyfr w następnej kolumnie. Identycznie postępujemy w systemie dziesiętnym, tyle że tam jest to o wiele bardziej skomplikowane. Na razie załóżmy, iż od liczb większych odejmujemy mniejsze (w przeciwnym razie musielibyśmy wprowadzić liczby ujemne, a nie chcemy tego robić w tym miejscu). Przykład: Wykonać odejmowanie w systemie binarnym 1101110 (2) - 1111 (2).
1101110-1111 1. Obie liczby umieszczamy jedna pod drugą tak, aby ich cyfry znalazły się w kolumnach o tych samych wagach: 1 1 10 1 11 0-1 11 1 1 2. Odejmowanie rozpoczynamy od cyfr ostatniej kolumny. Wyniki zapisujemy pod kreską. W tym przykładzie odjęcie ostatnich cyfr 0-1 daje wynik 1 oraz pożyczkę do następnej kolumny. Pożyczki zaznaczamy kolorem czerwonym. 11 1 10 1 11 0-1 11 1 1 1 3. Odjęcie cyfr w drugiej od końca kolumnie daje wynik 1-1 = 0. Od tego wyniku musimy odjąć pożyczkę 0-1 = 1 i pożyczka do następnej kolumny. 11 1 11 1 10 1 11 0-0 00 1 11 1 1 01 1 11 1 4. Według tych zasad kontynuujemy odejmowanie cyfr w pozostałych kolumnach. Pamiętaj o pożyczkach! Jeśli w krótszej liczbie zabraknie cyfr, to możemy kolumny wypełnić zerami: 1101110 (2) - 1111 (2) = 1011111 (2) (110 (10) - 15 (10) = 95 (10) ). Oto kilka dalszych przykładów: 1 11 1 11 1 1 00 0 00 0 0-0 00 0 00 0 1 0 11 1 11 1 1 1111 1 1 1 1 0 00 0-0 0 0 0 1 11 1 1 1 1 0 0 00 1 1 1 1 1 1 01 0 10 1 0-0 10 1 01 0 1 0 10 1 01 0 1
Mnożenie dwójkowe Naukę mnożenia binarnego rozpoczynamy od tabliczki mnożenia. 0 0 = 0 0 1 = 0 1 0 = 0 1 1 = 1 Tabliczka mnożenia binarnego (podobnie jak w systemie dziesiętnym) posłuży do tworzenia iloczynów częściowych cyfr mnożnej przez cyfry mnożnika. Iloczyny te następnie dodajemy wg opisanych zasad i otrzymujemy wynik mnożenia. Przykład: Pomnożyć binarnie liczbę 1101 (2) przez 1011 (2). 1. Obie liczby umieszczamy jedna pod drugą tak, aby ich cyfry znalazły się w kolumnach o tych samych wagach: 1101 1011 2. Każdą cyfrę mnożnej mnożymy przez poszczególne cyfry mnożnika zapisując wyniki mnożeń w odpowiednich kolumnach - tak samo postępujemy w systemie dziesiętnym, a tutaj jest nawet prościej, gdyż wynik mnożenia cyfry przez cyfrę jest zawsze jednocyfrowy: 11 0 1 10 1 1 11 0 1 1 10 1 0 0 00 11 0 1 Zwróć uwagę, iż wynikiem mnożenia mnożnej przez cyfrę mnożnika jest powtórzenie mnożnej z przesunięciem o pozycję cyfry (cyfra mnożnika 1) lub same zera (cyfra mnożnika 0). Spostrzeżenie to bardzo ułatwia konstrukcję układów mnożących.
3. Puste kolumny uzupełniamy zerami i dodajemy do siebie wszystkie cyfry w kolumnach. Uważaj na przeniesienia. 1 1 0 1 1 0 1 1 0 0 0 1 1 0 1 0 0 1 1 0 1 0 + 1 1 0 1 0 0 0 1 0 0 0 1 1 1 1 Sprawdź, czy otrzymany wynik jest poprawny. Oto kilka dalszych przykładów: 101 111 101 101 + 101 100011 1011 110 0000 1011 + 1011 1000010 111 111 111 111 + 111 110001