Kurs Assemblera cz. 7

 

SKOKI – KOMPUTER ŻABKĄ

Jak zapewne spostrzegteś, komputer ma już prostą umiejętność wypisywania głupot (czasem i mądrości, ale dużo, dużo rzadziej) na swoim ekranie. Czyli odpowiednie procedury już „siedzą” gdzieś we wnętrzu naszej maszyny. Najlepszym miejscem jest ku temu pamięć ROM, która to potrafi przechowywać swą zawartość niezależnie od tego, czy jest zasilana prądem, czy też nie. Dodatkową jej zaletą jest fakt, że nie da się zmienić jej zawartości.

No, ale dość tych głupot, przejdźmy do konkretów. Żeby wydrukować na ekranie jakąś literę trzeba nam było najpierw wstawić ją do akumulatora rozkazem LDA a potem wyrzucić na ekran jakimś innym rozkazem (STA, ale to pomińmy). Dużym ułatwieniem naszej pracy byłby, po pobraniu numeru litery, skok do jakiejś procedury (ach, stodkie języki wyższego rzędu i ich procedury!) bez przejmowania się, cóż mądrego jest właściwie w tych procedurach, byle jeno robiły, co chcemy (czyli drukowały litery; jeszcze, ale już niedługo – nie tylko).

W ROM C-64 istnieje procedura, która nazywa się tajemniczo „CHROUT’. Skrzaty mówią, że przy układaniu jej nazwy chodzito głównie o to, by nie dało się jej wymówić. A oznacza ona CHaRacter OUTput, czyli – wypchnięcie znaku. Służyć może do różnych celów – do wydrukowania danego znaku na drukarce, zapisania na dysku, albo (i o to właśnie chodzi) – na ekranie. Wystarczy jedynie wstawić znak do akumulatora (LDA) i skoczyć…

Krótkie, proste, ale skuteczne. Mamy „A”. Jeśli pomyślisz chwilę, zaraz się domyślisz, jak tą metodą drukować dłuższe wyrazy, czy całe zdania. Przy czym ciekawe jest, że wcale nie interesuje nas, jak to się dzieje – litera po prostu się pokazuje i już. Łatwo zauważyć, że działamy tutaj metodą taką samą, jak np. w BASIC-u czy PASCAL-u – jeżeli pewna część programu musi być powtarzana więcej razy, prościej jest odwoływać się do niej kiedy trzeba, a nie wpisywać przy każdej konieczności. Dzięki temu możliwe staje się osławione programowanie strukturalne. Swoją drogą, jeżeli nie byłoby ono możliwe w asemblerze, jak można by wyobrazić sobie taką możliwość w jakimkolwiek innym języku? Asembler to podstawa. WSZYSTKO, co można zrobić np. w BASIC-u – zostato już wcześniej zrobione w asemblerze, tylko że nie przez nas, lecz przez autorów interpretera.

Rozkaz JSR może więc nam stużyć, jeżeli chcemy z jakiegokolwiek miejsca programu skoczyć do innego. Dodatkową zaletą tego rozkazu jest fakt, że w pewnym miejscu pamięci, zwanym STOSem przechowuje adres, do którego powinien wrócić po wykonaniu procedury. Powrót następuje automatycznie, po napotkaniu rozkazu RTS. Jeżeli procesor trafi na ten rozkaz, to powraca do głównego biegu programu.

Innym „skaczacym” rozkazem jest JMP (JuMP). Jego cechą jest to, że skacze bezpośrenio pod wskazany adres i nie zostawia żadnych znaków szczególnych (takich jak JSR na stosie), by można byto go po nich wyśledzić. Jeżeli skoczymy gdzieś poprzez JMP, nie istnieje możliwość powrotu do poprzedniej częsci programu. Rozkaz ten działa więc tak samo jak instrukcja GOTO w BASIC-u.

Jeszcze winien jestem wyjaśnienia w sprawie dalszego uproszczenia drukowania tekstów na ekranie. Otóż w pewnym miejscu w pamięci ROM istnieje procedura, która ma za zadanie wyświetlenie zadanego tekstu. Ot, i wszystko. Nie musimy już w tym celu konstruować pętli, pobierać kolejnych znaków itd. Wszystko zrobili już za nas autorzy systemu operacyjnego. Trzeba tylko:

a) wiedzieć gdzie jest ta procedura,
b) umieć zlecić komputerowi jej wykonanie, czego właśnie mam zamiar Was nauczyć.

Na początek muszę Wam przekazać, jak komputer zapisuje w pamięci dłuższe adresy. Robi to za pomocą tzw. starszych i młodszych bajtów. Aby wyliczyć jakiś adres mając starszy i mtodszy bajt, trzeba ten starszy przemnożyć przez 256 i do wyniku dodać młodszy. Brzmi to może nieco zawile, ale nie zapominajmy, że myślimy ciągle systemem dziesiętnym (ach, gdyby tak Bóg stworzył cztowieka z szesnastoma palcami!), komputer zaś dwójkowym, którego skróconym zapisem jest system szesnastkowy. Dlatego też roztożenie liczby dwubajtowej (czyli większej niż 255, $ff) jest w systemie szesnastkowym proste, w dziesiętnym zaś – już nie tak bardzo. Dla liczby $1234 starszy bajt (z angielska MSB – More Significant Byte) wynosi $12, zaś młodszy (LSB – Less Significant Byte) – $34. Liczbę dzielimy więc po prostu na dwie części. Pierwsze dwie cyfry to bajt starszy, dwie ostatnie – młodszy. Zaś w systemie dziesiętnym rozpiska liczby 12345 wygląda tak: 12345 dzielimy na 256 (tu ukłon w stronę red. Kalkulatora), wynik: 48.222656. Od tego odrzucamy część po przecinku, zostaje więc 48. I to jest starszy bajt. Przechodzimy więc do młodszego. Pomnóżmy 48 przez 256, wyjdzie 12288. Teraz musimy jeszcze od naszej początkowej liczby (12345) odjąć to nieszczęsne 12288. Mi wyszto 57. Ten etap byt zresztą najbardziej dramatyczny. Stary, blisko pięciocentymetrowej (!) grubości Texas Instruments odmówił współpracy i musiałem szukać czegoś innego. Sprawdźmy jednak, czy wynik jest prawdziwy. 48*256+57=12345. Wszystko się więc zgadza. Dla porządku przedstawię jeszcze algorytmy w BASIC-u:

MSB=I NT(AD/256)
LSB=AD-256*MSB

Na pewno przydadzą się nie raz. Do czego jednak byty potrzebne w tym przypadku? Do poinformowania komputera o adresie, od którego zaczyna się tekst do wyświetlenia na ekranie. Wpiszmy teraz jakiś tekst do pamięci, od adresu – niech będzie $3000, czyli 12288, posługując się metodą przedstawioną przeze mnie w poprzednim odcinku. Tym razem jednak koniecznie wstaw na końcu znaczek „@” o kodzie $00, 0. Gotowe? Jeśli tak, to wpisz:

…i uruchom to jak zwykle – SYS 10000, G2710, czy strzałka w lewo, 3 i S. Teraz na ekranie pojawił się cały potrzebny Ci tekst, bez bólu, szybko i skutecznie. Jeżeli masz ochotę tekst ten jeszcze jakoś sformatować, zmienić kolory, czy co tam jeszcze – skorzystaj z tabeli kodów ASCII znajdującej się gdzieś pod koniec instrukcji obsługi. Jak widać, rolę starszego i młodszego bajtu wzięty na siebie dwa rejestry procesora – jako starszy wystąpił rejestr Y, jako młodszy – akumulator. Jest więc, jak obiecałem – umiemy wydrukować tekst za pomocą jednego rozkazu.

A teraz miła niespodzianka dla użytkowników TurboAssemblera. Nie wiem, czy metoda ta zadziała w innych programach tego typu, ja sprawdziłem ją jeszcze w Magic Assemblerze. Wpisz (tym razem monitorowcy mogą np. zamknąć oczy):

Działa? I to jak! Od tej chwili możesz w ten sposób ułatwić sobie działania na młodszych i starszych bajtach tym właśnie prostym sposobem, o czym zawiadamia ostrzący przy szkwatach

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *