Art of Assembly polskie wydanie.pdf

(18231 KB) Pobierz
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
WYLACZNOŚĆ DO PUBLIKOWANIA TEGO TEKSTU, POSIADA
RAG
WWW.R-AG.PRV.PL
„THE ART OF ASSEMBLY LANGUAGE”
tłumaczone by KREMIK
konsultacja naukowa NEKRO
wankenob@priv5.onet.pl
nekro@pf.pl
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
ROZDZIAL PIERWSZY: REPREZENTACJA DANYCH
Prawdopodobnie największą przeszkodą jaką większość początkujących napotyka kiedy próbuje nauczyć się
asemblera jest powszechne używanie binarnego i heksadecymalnego systemu liczbowego. Wielu programistów sądzi
że liczby heksadecymalne stanowią absolutny dowód na to, że Bóg nigdy nie planował aby ktokolwiek pracował w
asemblerze. Chociaż to prawda, że liczby heksadecymalne trochę się różnią od tego czego używamy na co dzień, ich
zalety znacznie przewyższają ich wady. Pomimo to, opanowanie tych systemów liczbowych jest ważne ponieważ ich
zrozumienie upraszcza inne ważne tematy wliczając w to algebrę boolowską i projekt logiczny, reprezentację
numeryczną znaków, kody znaków i dane upakowane.
1.0 WSTĘP
Ten rozdział omawia kilka ważnych pojęć, w tym binarny i heksadecymalny system liczbowy, organizację danych
binarnych (bity ,nibbles ,bajty ,słowa i podwójne słowa),system liczb ze znakiem i bez znaku, operacje
arytmetyczne, logiczne, przesunięcia i obroty na wartościach binarnych, pola bitów i pakowanie danych ,zbiór
znaków ASCII. Jest to podstawowy materiał a dalsze czytanie tego tekstu zależy od zrozumienia tych pojęć. Jeśli już
jesteś zapoznany z tymi terminami z innych kursów lub studiów powinieneś przynajmniej przejrzeć ten materiał
przed przystąpieniem do następnego rozdziału. Jeśli nie jesteś zapoznany lub tylko ogólnikowo ,powinieneś
przestudiować go starannie. CAŁY MATERIAŁ W TYM ROZDZIALE JEST WAŻNY! Nie opuszczaj nadmiernie
materiału.
1.1 SYSTEMY LICZBOWE
Większość nowoczesnych systemów komputerowych nie przedstawia wartości liczbowych używając systemu
dziesiętnego. Zamiast tego, używają systemu binarnego lub systemu "dopełnienia do dwóch" .Żeby zrozumieć
ograniczenia arytmetyki komputerów musimy zrozumieć w jaki sposób komputery przedstawiają liczby.
1.1.1 PRZEGLĄD SYSTEMU DZIESIĘTNEGO
Używasz systemu dziesiętnego (opartego o 10) od tak dawna, że uważasz go za pewnik. Kiedy widzisz liczbę taką
jak *123*,nie myślisz o wartości 123;raczej stwarzasz umysłowy obraz tego jaką pozycję ta wartość przedstawia. W
rzeczywistości, liczba 123 przedstawia
1*10 2 +2*10 1 +3*10 0
lub
100+20+3
Każda cyfra pojawiająca się po lewej stronie przecinka przyjmuje wartość między zero a dziewięć
mnożone przez dodatnie potęgi liczby dziesięć. Cyfra pojawiająca się po prawej stronie przecinka przyjmuje
wartości między zero a dziewięć mnożone przez rosnące, ujemne potęgi liczby dziesięć. Na przykład wartość
123,456 to:
1*10 2 2 +2*10 1 1 +3*10 0 0 +4*10 -1 -1 +5*10 -2 -2 +6*10 -3
lub
100+20+3+0.4+0.05+0.006
965452570.006.png 965452570.007.png 965452570.008.png
 
1.1.2 BINARNY SYSTEM LICZBOWY
Większość nowoczesnych systemów komputerowych (w tym IBM PC) działa używając logiki binarnej. Komputer
przedstawia wartości używając dwóch poziomów napięcia (zwykle 0V i 5V).Poprzez dwa takie poziomy możemy
przedstawić dokładnie dwie rożne wartości. To mogłyby być dowolne dwie rożne wartości ale konwencjonalnie
używamy wartości zero i jeden. Te dwie wartości, zbiegiem okoliczności, odpowiadają dwom cyfrom używanym
przez binarny system liczbowy. Ponieważ jest zgodność między logicznymi poziomami używanymi przez 80x86 i
dwoma cyframi używanymi w binarnym systemie liczbowym, nie było niespodzianki, ze IBM PC zastosował
binarny system liczbowy. Binarny system liczbowy pracuje tak jak system dziesiętny z dwoma wyjątkami: system
binarny uznaje tylko cyfry 0 i 1 (zamiast 0-9) i system binarny używa potęgi dwa zamiast potęgi dziesięć. Dlatego
tez jest bardzo łatwo przekształcić liczbę binarna na dziesiętną. Dla każdego "1" lub ”0” w łańcuchu binarnym
dodajemy 2 n gdzie n jest pozycja cyfry binarnej liczonej od prawej strony (zera)Na przykład binarna
wartosc11001010 (2) przedstawia się tak:
1*2 7 +1*2 6 +0*2 5 +0*2 4 +1*2 3 +0*2 2 +1*2 1 +0*2 0
lub
8+64+8+2
=
202 (10)
Przekształcenie liczby dziesiętnej na binarna jest odrobinę bardziej skomplikowane Musisz znaleźć te potęgi dwójki,
które dodane razem stworzą rezultat dziesiętny. Najłatwiejsza metoda to zacząć od dużych potęg dwójki aż do
2 0 .Rozważmy dziesiętną wartość 1359:
* 2 10 =1024. 2 11 =2048. 1024 jest największą potęga dwójki mniejszą niż 1359. Odejmujemy 1024 od 1359 i
zaczynamy wartość binarna od lewej cyfra "1".Binarnie = "1".Resultat dziesiętny to 1359-1024=335.
* Kolejna ,niższa potęga dwójki (2 9 =512) jest większa niż powyższy rezultat, więc dodajemy "0" na koniec
binarnego łańcucha. Binarnie="10",dziesiętnie jest wciąż 335
* Kolejną, niższą potęgą dwójki jest 256 (2 8 ).Odejmujemy ją od 335 i dodajemy cyfrę "1" na koniec binarnej
liczby.Binarnie="101",rezultat dziesiętny to 79.
* 128 (2 7 ) jest większe niż 79 więc dołączamy "0" do końca łańcucha binarnego. Binarnie ="1010",rezultat
dziesiętny pozostaje 79.
* Następna niższa potęga dwójki (2 6 =64) jest mniejsza niż 79,wiec odejmujemy 64 i dołączamy "1" do końca
binarnego łańcucha. Binarnie ="10101".Rezultat dziesiętny to 15
* 15 jest mniejsze niż następna potęga dwójki (2 5 =32) więc po prostu dodajemy "0" do końca łańcucha
binarnego.Binarnie="101010".Dziesietny rezultat to wciąż 15.
* 16 (2 4 ) jest większa niż dotychczasowa reszta więc dołączamy "0" do końca łańcucha
binarnego.Binarnie="1010100",rezultat dziesiętny to 15.
* 2 3 (osiem) jest mniejsze niż 15 więc dokładamy następna cyfrę "1" na koniec binarnego
lancucha.Binarnie="10101001",dziesiętnie rezultat to 7.
* 2 2 jest mniejsze niż 7 więc odejmujemy cztery od siedmiu i dołączamy następną jedynkę do binarnego
lancucha.Binarnie="101010011",dziesietnie jest 3.
* 2 1 jest mniejsze niż 3 więc dodajemy jedynkę do łańcucha binarnego i odejmujemy dwa od wartości
dziesiętnej.Binarnie="1010100111",dziesiętny rezultat to teraz 1.
* Ostatecznie rezultat dziesiętny wynosi jeden ( 2 0 ) wiec dodajemy końcową "1" na koniec łańcucha binarnego.
Końcowy rezultat binarny to: 10101001111
Liczby binarne, mimo iż maja małe znaczenie w językach programowania wysokiego poziomu, pojawiają się
wszędzie w programach pisanych w asemblerze.
1.1.3 FORMAT DWÓJKOWY
Każda binarna liczba zawiera bardzo duża liczbę cyfr (lub bitów - skrót od BInary digiTs).Na przykład
,przedstawiamy liczbę pięć poprzez:
101 00000101 0000000000101 000000000000101
Dowolna liczba zera może poprzedzać liczę binarną bez zmiany jej wartości. Przyjmiemy konwencję ignorowania
poprzedzających zer. Na przyklad,101 (2) przedstawia liczbę pięć .Ponieważ 80x86 pracuje z grupami ośmiobitowymi,
przyjdzie nam dużo łatwiej rozszerzyć o zera wszystkie liczby binarne jako wielokrotności czterech lub ośmiu bitów.
Dlatego tez podążając za konwencja, przedstawimy liczbę pięć jako 0101 (2) lub 00000101 (2) .
W USA większość ludzi oddziela każde trzy cyfry przecinkiem, co czyni duże liczby łatwiejszymi do odczytu, na
przykład 1,023,435,208 jest dużo łatwiejsze do przeczytania i pojęcia niż 1023435208.Przyjmiemy podobną
koncepcje w tym tekście dla liczb binarnych. Oddzielimy każdą grupę czterech bitów spacją. Na przykład binarną
wartość 1010111110110010 zapiszemy jako 1010 1111 1011 0010.
Często pakujemy kilka wartości razem do tej samej liczby binarnej. Jedna z form instrukcji MOV 80x86 używa
binarnego kodowania 1011 0rrr dddd dddd dla spakowania trzech pozycji do 16 bitów; pięć bitów kodu operacji
(10110),trzy bity pola rejestrów (rrr) i osiem bitów wartości bezpośredniej (dddd dddd).Dla wygody, przydzielimy
wartości liczbowe każdej pozycji bitu .Ponumerujemy każdy bit jak następuje:
1) Bit najbardziej na prawo jest bitem z pozycji zero.
2) Każdy bit na lewo ma kolejny ,większy numer
Ośmiobitowa wartość binarna używa bitów od zero do siedem:
x 7 ,x 6 ,x 5 ,x 4 ,x 3 ,x 2 ,x 1 ,x 0
Szesnastobitowa wartość binarna używa bitów od zera do piętnastu:
x 15 ,x 14 ,x 13 ,x 12 ,x 11 ,x 10 ,x 9 ,x 8 ,x 7 ,x 6 ,x 5 ,x 4 ,x3,x 2 ,x 1 ,x 0
Do bitu zerowego zazwyczaj odnosimy się jako najmniej znaczącego bitu (L.O). Bit najbardziej z lewej strony jest
zwykle nazywany bitem najbardziej znaczącym (H.O.). Będziemy się odnosili do bitów pośrednich poprzez ich
numery.
1.2 ORGANIZACJA DANYCH
W czystej matematyce wartości mogą zawierać przypadkowe liczby bitów. Komputery ,generalnie rzecz biorąc
pracują z określoną liczbą bitów. Powszechnie przyjęte to pojedyncze bity, grupy czterech bitów (zwane
nibbles),grupy ośmiu bitów (zwane bajtami),grupy szesnastu bitów (zwane słowem) i więcej. Ich rozmiary nie są
przypadkowe. Ta sekcja opisze grupy bitów powszechnie używanych w chipach Intela 80x86
1.2.1 BITY
Najmniejsza "jednostka” danych w komputerze jest pojedynczy bit. Ponieważ pojedynczy bit jest zdolny do
przedstawiania tylko dwóch rożnych wartości (typowo zero i jeden),możemy odnieść wrażenie, ze jest bardzo mało
wartości jakie może przedstawić pojedynczy bit. Nie prawda! Jest ogromna liczba pozycji jakie możemy przedstawić
za pomocą pojedynczego bitu.
Za pomocą pojedynczego bitu możemy przedstawić dwie odrębne pozycje. Przykładem mogą być: zero lub jeden,
prawda lub fałsz, włączony lub wyłączony, mężczyzna lub kobieta, Jednakże nie jesteśmy ograniczeni do
przedstawiania typów danych binarnych (to znaczy tych obiektów które maja dwie rożne wartości). Możesz używać
pojedynczego bitu do przedstawiania liczb 723 i 1,245 lub 6.254 i 5. Możesz również użyć pojedynczego bitu do
przedstawiania kolorów czerwonego i niebieskiego. Możesz nawet przedstawić dwa nie powiązane ze sobą obiekty
za pomocą pojedynczego bitu. Na przykład, możesz przedstawić kolor czerwony i liczbę 3.256 za pomocą
pojedynczego bitu. Możesz przedstawić jakieś dwie rożne wartości za pomocą pojedynczego bitu. Jednakże możesz
przedstawić tylko dwie rożne wartości za pomocą pojedynczego bitu.
To mylące rzeczy, nawet bardzo, rożne bity mogą przedstawiać rożne rzeczy. Na przykład jeden bit może być
używany do przedstawiania wartości zero i jeden, podczas gdy sąsiedni bit może być używany do przedstawiania
wartości prawda i fałsz .Jak można to odróżnić patrząc na te bity? Odpowiedź, nie można. Ale to ilustruje cała ideę
komputerowej struktury danych: dana jest to to co ty zdefiniujesz. Jeśli użyjesz bitu do przedstawienia boolowskiej
(prawda/ fałsz) wartości wówczas ten bit (zdefiniowany przez ciebie) reprezentuje prawdę lub fałsz. Dla bitów
mających prawdziwe znaczenie musisz być konsekwentny. To znaczy ,jeśli używasz bitu do przedstawiania prawdy
lub fałszu w jednym punkcie swojego programu nie powinieneś używać wartości prawda/fałsz przechowywanej w
tym bicie do późniejszego przedstawiania koloru czerwonego lub niebieskiego.
Ponieważ większość danych których będziesz używał, wymaga więcej niż dwóch rożnych wartości, pojedyncze
wartości bitów nie są najbardziej powszechnymi typami danych, które będziesz stosował. Ponieważ wszystko inne
składa się z grup bitów, bity odgrywają ważną role w twoich programach. Oczywiście, jest kilka typów danych które
wymagają dwóch odrębnych wartości, wiec wydaje się, ze bity są ważne same w sobie. Jednak wkrótce zobaczysz,
że pojedyncze bity są trudne do manipulowania, wiec często będziemy używać innych typów danych do
przedstawiania wartości boolowskich.
1.2.2 NIBBLESY
965452570.001.png 965452570.002.png
 
Nibble jest zbiorem czterech bitów. To nie jest szczególnie interesująca struktura danych za wyjątkiem dwóch
przypadków: liczb BCD (Binary Coded Decimal) i liczb heksadecymalnych. Cztery bity przedstawiają pojedynczą
cyfrę BCD lub heksadecymalną. Przy pomocy nibble’a możemy przedstawić do 16 odrębnych wartości. W
przypadku liczb heksadecymalnych, wartości 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E i F są przedstawiane przez cztery bity
(zobacz "Heksadecymalny System Liczbowy” ).BCD używa 10 rożnych cyfr (0,1,2,3,4,5,6,7,8,9) i wymaga czterech
bitów. Faktycznie, każda z szesnastu odrębnych wartości może być przedstawiana przez nibble’a, ale cyfry
heksadecymalne i BCD są podstawowymi pozycjami jakie możemy przedstawić za pomocą pojedynczego nibble'a.
1.2.3 BAJTY
Bez wątpliwości, najważniejszą strukturą danych używaną przez mikroprocesor 80x86 jest bajt .Bajt składa się z
ośmiu bitów i jest najmniejszym adresowalnym elementem danych w mikroprocesorze 80x86.Adresy pamięci
głównej jak i I/O w 80x86 wszystkie są adresami bajtowymi. To znaczy, ze najmniejsza pozycja która może być
dostępna przez program w 80x86 jest wartością ośmiobitową. Dostęp do czegokolwiek mniejszego wymaga abyś
odczytał bajt zawierający dane i zamaskował niechciane bity. Bity w bajcie są zazwyczaj numerowane od zera do
siedem, przy użyciu konwencji przedstawionej na rysunku 1.1.
Bit 0 jest najmniej znaczącym bitem, bit 7 jest najbardziej znaczącym bitem. Do pozostałych bitów będziemy się
odwoływać poprzez ich numery.
Rysunek 1.1 Numerowanie bitów w bajcie
Zauważ, że bajt także zawiera dwa nibble (zobacz rysunek 1.2)
Rysunek 1.2 Dwa nibble w bajcie
Bity 0..3 stanowią mniej znaczącego nibble'a, bity 4..7 bardziej znaczącego nibble'a. Ponieważ bajt zawiera
dokładnie dwa nibble, wartość bajtu wymaga dwóch cyfr heksadecymalnych. Ponieważ bajt zawiera osiem bitów,
można przedstawić 2 8 ,lub 256, rożnych wartości. Generalnie będziemy używać bajtu do przedstawiania wartości
liczbowych w zakresie 0...255,liczb ze znakiem w zakresie -128..+127 (zobacz "Liczby ze znakiem i bez znaku"
),kodów znaków ASCII/IBM, i innych specjalnych typów danych wymagających nie więcej niż 256 rożnych
wartości. Wiele typów danych ma mniej niż 256 pozycji, więc osiem bitów jest zazwyczaj wystarczających.
Ponieważ 80x86 jest maszyną adresowalna bajtem (zobacz "Układ Pamięci i Dostęp") okazuje się bardziej
efektywne manipulowanie całym bajtem niż pojedynczym bitem czy nibble'm. Z tego powodu większość
programistów używa całego bajtu do przedstawienia typu danych który wymaga nie więcej niż 256 pozycji, nawet
jeśli mniej niż osiem bitów wystarczyłoby. Na przykład, często przedstawiamy wartości boolowskie prawdę i fałsz
(odpowiednio) jako 00000001 (2) i 00000000 (2) .
Prawdopodobnie najważniejszym zastosowaniem bajtu jest udział w kodzie znaku. Znaki pisane z klawiatury,
wyświetlane na ekranie, i drukowane na drukarce, wszystkie mają wartości liczbowe. Pozwala to porozumiewać się
z resztą świata, IBM PC używa wariantu ze znakami ASCII (zobacz "Zbiór znaków ASCII”). Jest 128
zdefiniowanych kodów w zbiorze znaków ASCII.IBM używa pozostałych 128 możliwych wartości dla
rozszerzonego zbioru kodów znaków wliczając w to znaki europejskie ,symbole graficzne, litery greckie i symbole
matematyczne.
1.2.4 SŁOWA
965452570.003.png 965452570.004.png
 
Słowo jest grupą 16 bitów. Ponumerujemy te bity zaczynając od zera w gore aż do piętnastu. Numeracja bitów
pokazana jest na rysunku 1.3
Rysunek 1.3 Numeracja bitów w słowie
Tak jak przy bajcie, bit 0 jest najmłodszym bitem a bit 15 najstarszym bitem. Kiedy odnosimy się do innych bitów w
słowie używamy ich numerów pozycji.
Zauważ, ze słowo zawiera dokładnie dwa bajty. Bity 0 do 7 tworzą mniej znaczący bajt, bity od 8 do 15 tworzą
bardziej znaczący bajt.(Zobacz rysunek 1.4)
Rysunek 1.4 Dwa bajty w słowie
Naturalnie, słowo może być dalej rozbite na cztery nibble jak pokazuje rysunek 1.5
Rysunek 1.5 Nibble w słowie
Nibble zero jest najmniej znaczącym nibblem w słowie a nibble trzy najbardziej znaczącym nibblem słowa.
Pozostałe dwa nibble to "nibble jeden" i nibble dwa".
Mając 16 bitów możemy przedstawić 2 16 (65,536) rożnych wartości. To mogą być wartości w zakresie od 0 do 65
536 (lub zazwyczaj -32,768..+32,767) lub każdy inny typ danych o wartościach nie większych niż 65,536.Trzy
ważne zastosowania dla słowa to wartości liczb całkowitych, offsetów i wartości segmentów (zobacz "Układ
Pamięci i Dostęp” przy opisie segmentów i offsetów).
Słowa mogą reprezentować wartości całkowite w zakresie 0..65 536 lub -32,768..+32,767.Wartości liczb bez znaku
są reprezentowane przez wartości binarne zgodne z bitami w słowie. Wartości liczb ze znakiem używają formy
„dopełnienia do dwóch” dla wartości liczbowych (zobacz "Liczby ze znakiem i bez znaku").Wartości segmentu,
które są zawsze długie na 16 bitów stanowią adres paragrafu kodu, danych, danych specjalnych lub segmentu stosu
w pamięci.
1.2.5 PODWÓJNE SLOWO
Podwójne słowo jest dokładnie tym, na co wskazuje jego nazwa, parą słów .Dlatego tez długość podwójnego słowa
wynosi 32 bity ,jak pokazuje rysunek 1.6.
965452570.005.png
Zgłoś jeśli naruszono regulamin