----------------Uwaga! Proszë zîoûyê dwuszpaltowo-------------------- Asembler (cz. 2.) ----------------- PIERWSZE KROKI -- No, no... kurs asemblera. A moûe by tak lepiej strzeliê sobie CZARNEGO LESZKA? -- Co? W twoim wieku? -- Po ostatniej lekcji sië zaîamaîem -- chyba sië tego nie nauczë. -- Spoko, kolego. Rozkazy asemblera wcale nie sâ takie trudne. -- Coooo?? Rozkazy??? To nie wystarczy mieê ASM-One'a? -- Siadaj, stary, i nie marudú, ja Cië wszystkiego nauczë... Minëîy dwa impulsy elektryczne. Na ekranie monitora pojawiî sië ASM-One. Dwa palce energicznie wystukaîy kilka poleceï. Jako ostatni naciôniëty zostaî klawisz [Esc]. -- No to jesteômy w edytorze. Teraz napiszë kod úródîowy. I ûadnych pytaï, dopóki nie skoïczë. Dopiero wtedy na wszystko odpowiem. move.l #'abcd',d0 move.l 1234,d1 lea Tekst,a1 move.l Tekst,d5 rts Tekst: dc.b 'To jest tekst napisany przeze mnie',0 -- To dla mnie za trudne. Rezygnujë z kursu. -- Nie gadaj! Zaraz wszystko zrozumiesz. Jedziemy od poczâtku. Popatrz na pierwszâ linië programu. Zaczyna sië kilkoma spacjami, gdyû... -- Tego sië uczyîem juû miesiâc temu (kaûdy rozkaz musi byê poprzedzony co najmniej jednâ spacjâ lub tabulatorem), ale co dalej? -- Dalej znajduje sië rozkaz. -- A zatem "move.l #'abcd',C0" to jest rozkaz? -- Nie! Rozkaz moûe sië skîadaê tylko z jednego wyrazu. -- Czy w takim razie rozkazem jest 'move.l'? -- Prawie, nazwy rozkazu czyta sië tylko do kropki. Pierwszym rozkazem jest "MOVE". -- Co zatem oznacza: '.L #'abcd',d0'? -- Po kolei. Najpierw Ci wyjaônië, co oznacza '.L' Wiëkszoôê rozkazów ma rozszerzenie .b, .w lub .l. Litera oznacza, ile danych ma zostaê wziëtych pod uwagë. b (ang. byte) oznacza bajt, a odpowiada to jednemu znakowi w tekôcie... -- Nie rozumiem. -- No... Kaûdy znak (litera, spacja, liczba, tabulator itd.) to jest jeden bajt. -- Czy w takim razie trzy litery (np. abc) to trzy bajty? -- Oczywiôcie. Ale kontynuujmy. Jak juû powiedziaîem: b (w rozszerzeniu rozkazu) oznacza bajt, w (ang. word) -- sîowo, czyli dwa bajty (dwa znaki w tekôcie). -- W takim razie szeôê znaków (np. abc2D#) to 6 bajtów, ale 3 sîowa? -- Tak. Natomiast litera l (ang. long word) oznacza jedno dîugie sîowo (odpowiada to dwóm sîowom, czyli czterem bajtom). -- Zatem osiem znaków (np. abcdefgm) to 8 bajtów, 4 sîowa, ale 2 dîugie sîowa. -- Fenomenalnie. Jednak wróêmy do naszego programu. Rozkaz move dziaîa podobnie, jak DOS-owy rozkaz copy -- kopiuje dane z jednego miejsca w drugie. -- A zatem: move.b przeôle tylko jeden bajt, move.w jedno sîowo (czyli 2 bajty), a move.l -- jedno dîugie sîowo (4 bajty). -- Oczywiôcie... Po rozkazie move podane sâ dwa parametry, oddzielone przecinkiem. Jeûeli przed pierwszym z nich znajduje sië znak #, to oznacza to, ûe ten parametr to dana, którâ chcemy wysîaê. -- Jak to, dana? -- Jeôli napiszesz: "move.l #1234, ...", to znaczy, ûe wyôlesz liczbë 1234. Natomiast jeûeli nie ma ûadnego znaku, to pierwszy parametr oznacza miejsce, z którego dane majâ byê kopiowane. Drugi parametr, znajdujâcy sië bezpoôrednio po przecinku, oznacza miejsce, w które dane zostanâ przesîane. Polecenie move ma wiëc nastëpujâcâ postaê: move.(b/w/l) skâd/#dana,gdzie Lepiej zrozumiesz to na przykîadzie: move.b #1,d0 move.w #'12',d1 move.b #45,d3 move.b 45,d2 Zanalizujmy powoli pierwszâ linië. Na poczâtku znajduje sië kilka spacji (wiadomo, muszâ byê przed kaûdym rozkazem). Za nimi podany jest rozkaz move. Oznacza to, ûe bëdziemy gdzieô coô przesyîali. Rozkaz move ma rozszerzenie .b, a to znaczy, ûe przesyîany bëdzie tylko jeden bajt. Po poleceniu move widzimy krzyûyk. Wobec tego pierwszy parametr bëdzie danâ. Po prawej stronie krzyûyka znajduje sië liczba 1 -- przesyîana bëdzie liczba (bajt o wartoôci) 1. Drugi parametr wyjaônia, dokâd ta dana zostanie przesîana. W naszym wypadku liczba 1 skopiowana bëdzie do d0. -- A co oznacza to d0? -- Jest to tzw. rejestr. Twój procesor ma wiëcej takich rejestrów. -- Wprowadzasz mi nowe pojëcia i nie tîumaczysz ich. Co to sâ rejestry? -- Rejestry sâ to takie miejsca, w których moûesz coô przechowywaê (tak jak sië to robi w pudeîkach). W procesorze Amigi istniejâ dwa typy rejestrów: 8 rejestrów danych (d0,d1,d2,d3,d4,d5,d6,d7) i 8 rejestrów adresowych (a0,a1,a2,a3,a4,a5,a6,a7) -- Czym jedne róûniâ sië od drugich? -- Rejestry danych przechowujâ dane. Natomiast rejestry adresowe przechowujâ adresy miejsc, w których dane sië znajdujâ. -- Nie rozumiem, o co tu chodzi. -- Przypuôêmy, ûe masz na stole dwa pudeîka. Do jednego wîoûyîeô np. kartkë z numerem telefonu kolegi. Oznacza to, ûe to pudeîko jest rejestrem danych. Natomiast do drugiego wîoûyîeô kartkë z adresem tego kolegi. Jest to rejestr adresowy, z którego moûesz odczytaê, pod jakim adresem zostawiîeô danâ. -- No dobra! Rozumiem, ûe mogë coô poûyczyê koledze, ale komu mogë "poûyczaê" dane w komputerze? Klawiaturze? -- Nie, nie. Dane moûesz wysyîaê do pamiëci komputera. -- Czy w takim razie kaûde miejsce w pamiëci ma swój adres? -- Owszem. -- A ile danych moûna zmieôciê pod jednym adresem? -- Tylko jeden bajt. -- Jak to? To co sië stanie, jeôli pod adres 42 wyôlë cztery bajty (np. 4 litery: abcd)? -- Pierwsza litera bëdzie sië znajdowaê pod adresem 42, druga juû pod 43, trzecia pod 44 i ostatnia, czwarta, pod adresem 45. -- A jaki jest pierwszy i ostatni adres pamiëci? -- Pierwszym adresem jest adres 0. Natomiast ostatni zaleûy od iloôci pamiëci, w którâ wyposaûony jest komputer. -- Dobrze, rozumiem juû. Powróêmy zatem do naszego przykîadu. -- Bardzo chëtnie. Wiemy juû, ûe po wykonaniu piewszego rozkazu rejestr d0 bëdzie zawieraî liczbë 1. Przejdúmy wiëc do drugiej linii. Znajduje sië w niej rozkaz move. Ma on rozszerzenie .w. W takim razie przesyîane bëdzie jedno sîowo (dwa bajty). Spójrzmy na pierwszy parametr. Znajduje sië przed nim krzyûyk, a zatem bëdzie on oznaczaî danâ. Na prawo od krzyûyka znajdujâ sië dwie litery, zapisane w apostrofach. (Tekst ZAWSZE musi znajdowaê sië w apostrofach lub cudzysîowach.) Dlatego teû te dwie litery zostanâ przesîane do rejestru danych d1. Popatrzmy na kolejnâ linië. Widzimy, ûe dana o wielkoôci jednego bajtu przesîana bëdzie do rejestru danych d3. Tâ danâ jest liczba 45. Po wykonaniu tego rozkazu rejestr d3 bëdzie przechowywaî liczbë 45. -- Tak, ale dlaczego przesyîasz tylko jeden bajt (move.b), skoro do zapisania liczby 45 potrzeba 45 znaków? -- Nie myl liczb ze znakami. -- Mylë, bo nie powiedziaîeô mi, czym sië od siebie róûniâ? -- Kaûdy znak ma odpowiadajâcâ mu liczbë (tak zwane kody ASCII). Kody te sâ z zakresu od 0 do 255. Na przykîad 'A' ma 65; 'a' ma 97; '1' ma 49 itd. Polskie litery na Amidze w standardzie AmigaPL majâ tak dobrane kody ASCII, aby nie wejôê na juû istniejâce znaki. Na przykîad litera 'â' ma kod 226. Dla asemblera nie ma znaczenia, w jaki sposób przeôlesz mu znak. Dlatego teû oba te rozkazy: move.b #'a',d0 move.b #97,d0 dadzâ taki sam efekt. Zarówno w pierwszym, jak i w drugim wypadku do rejestru d0 przesîana zostanie liczba 97 ('a' ma kod 97). -- Czyli zamiast 'a' mogë przesyîaê 97 i odwrotnie? -- Owszem -- moûesz. -- Skoro zawsze przesyîana jest tylko liczba, to jak komputer rozpoznaje, czy dana jest znakiem, czy liczbâ? -- Komputer wszystko traktuje jako liczby. Nawet gdy wyôwietla tekst na ekranie, to sâdzi, ûe to tylko liczby. -- Czy w takim razie liczba 9 i pojawiajâcy sië na ekranie znak 9 to nie to samo? -- Aleû skâd. Pojawiajâca sië na ekranie dziewiâtka to znak o kodzie 57, natomiast znak o kodzie 9 to tabulator. Kontynuujmy jednak czytanie naszego przykîadu. Jego ostatnia linia wyglâda nastëpujâco: move.b 45,d2 Rozkaz move.b przesyîa jeden bajt (znak). Popatrzmy wiëc na pierwszy parametr. Nie ma tu krzyûyka, czyli oznacza on adres pamiëci, spod którego pobierana bëdzie dana. Tak wiëc znak, który znajduje sië pod adresem 45, zostanie przesîany do rejestru danych d2. -- No tak! Teraz juû rozumiem. Moûemy wiëc powróciê do naszego gîównego programu. Czy mogë spróbowaê sam go rozszyfrowaê? -- Aleû oczywiôcie! -- Tak wiëc pierwsza linia move.l #'abcd',d0 oznacza, ûe przesyîamy danâ o rozmiarze 1 dîugiego sîowa. Tâ danâ sâ cztery litery 'abcd' i przesyîane sâ one do rejestru danych d0. Teraz rejestr d0 zawiera tekst 'abcd', ale w kodach ASCII. (Pamiëtam, ûe a ma 97, b -- 98, c -- 99 d -- 100 itd.). Mam tylko jedno pytanie. Co sië stanie, jeûeli zamiast 'd0' napiszë 'd0'?------------------?-------------- -- Nie ma to dla programu ûadnego znaczenia. Kody ASCII sâ tak ustawione, ûe pomiëdzy kodem duûej i maîej litery jest staîy odstëp (32). Amiga sama sobie ustawi potrzebnâ wartoôê, ale tylko w rejestrach i rozkazach asemblera. Jeôli wpiszesz tekst, duûe i maîe litery pozostanâ takimi, jak je wpisaîeô (ich kody bëdâ sië róûniê). -- Teraz przechodzimy do drugiej linii move.l 1234,d1. Do rejestru danych d1 przesyîane jest jedno dîugie sîowo spod adresu 1234. W efekcie przesyîane sâ cztery bajty: pierwszy spod adresu 1234, drugi spod adresu 1235, trzeci 1236 i czwarty 1237. Kolejna linijka kodu úródîowego to: lea Tekst,a1. Oooo! To dla mnie nowy rozkaz. -- Owszem. Ale o tym powiem dopiero za miesiâc. -- Super! Zatem do nastëpnego numeru MA. -- No, do nastëpnego.