Informacje dodatkowe     Informacje dodatkowe o MC68000


Rejestry procesora MC68000 i stos

Po uruchomieniu każdego programu (pliku wykonywalnego - executable file) na Amidze, w rejestrach
D0-D7 i A0-A7 znajdują się różne wartości. Można je dowolnie zmieniać, ale dwa szczególne rejestry:
D0 i A7, przy zakończeniu wykonywania programu (instrukcją RTS), muszą mieć taką samą wartość,
jak na początku zaraz po jego uruchomieniu. W przeciwnym razie program wykona błąd i nastąpi
awaria systemu (często powodująca reset komputera). Aby zapamiętać wartości tych rejestrów można
je, np. odłożyć na stosie. W rejestrze A7 znajduje się adres wskazujący na bajt, który znajduje się za
obszarem 4096 bajtów pamięci stosu. Jest to standardowa ilość pamięci, przydzielana każdemu pro-
gramowi przez system operacyjny. Stos jest przeznaczony tylko i wyłącznie dla programu, któremu
został przydzielony. Operowanie pamięcią należącą do innego programu, najczęściej powoduje awarię
systemu (komunikat Software Failure). Na stosie są zapisywane 4-bajtowe adresy powrotu, po każdo-
razowym wykonaniu rozgałęzienia instrukcją BSR lub JSR. Po wykonaniu jednej z tych instrukcji, adres
w rejestrze A7 zmniejszy się o 4 i będzie wskazywał na 1-szy bajt, 4-bajtowego adresu powrotu. Adres
powrotu wskazuje na pamięć, zawierającą kod do realizowania po wykonaniu instrukcji RTS. Po jej
wykonaniu, adres w rejestrze A7 zwiększy się o 4, czyli powróci do stanu sprzed wykonania instrukcji
rozgałęzienia. Oprócz adresów powrotów, na stosie programista może zapisywać dowolne dane (np.
zawartość rejestrów Dx). Należy przy tym pamiętać, aby rozmiar tych danych w połączeniu z rozmiarem
adresów powrotów, nie przekroczył rozmiaru całego stosu. Wiedząc, że adres powrotu zajmuje 4-bajty
i znając rozmiar stosu można łatwo obliczyć, ile rozgałęzień instrukcją BSR lub JSR można wykonać
w programie. Np. jeśli program posiada stos o rozmiarze 4096 bajtów, to można w nim wykonać maksy-
malnie 1024 rozgałęzienia (4096/4). Standardowym rozmiarem stosu jest 4096 bajtów. Spotyka się pro-
gramy o dużo większym stosie, np. FileMaster 3, którego stos wynosi 10000 bajtów. Niektóre programy
wymagają do działania jeszcze większego stosu. Dla porównania system operacyjny Workbench ma
stos o rozmiarze 6000 bajtów.

Ograniczenia ALU procesora MC68000

Choć procesor Motorola 68000 ma 32-bitową architekturę wewnętrzną, to jego jednostka arytmetyczno-
logiczna nie potrafi mnożyć i dzielić z taką dokładnością (instrukcje MULU i DIVU). Jedynie dodawanie
i odejmowanie jest realizowane na słowie 32-bitowym. Istnieje jednak sposób na ominięcie tego ograni-
czenia, np. w przypadku mnożenia danej wartości przez 10. Załóżmy, że mamy pewną wartość w reje-
strze Dx, którą chcemy pomnożyć przez 10, z dokładnością 32-bitów.
Oto algorytm mnożenia 32-bitowego przez 10:

move.l  Dx,Da
rol.l   #3,Dx
add.l   Da,Dx
add.l   Da,Dx
          Dx: 00000001
Dx: 00000008
Dx: 00000009
Dx: 0000000A

32-bitowe mnożenie i dzielenie przez 2, 4, 8, 16, 32, 64, 128, 256 jest jeszcze prostsze. Aby pomnożyć
/podzielić wartość rejestru Dx z dokładnością 32-bitów, wystarczy przesunąć jego zawartość o x-bitów
w lewo/prawo. Na przykład:

Mnożenie przez 64:
Dx: 00000001
lsl.l #6,Dx
Dx: 00000040
        Mnożenie przez 512:
Dx: 00000001
lsl.l #8,Dx
lsl.l #1,Dx

Dx: 00000200
        Dzielenie przez 16:
Dx: 00000080
lsr.l #4,Dx
Dx: 00000008
        Dzielenie przez 1024:
Dx: 00004000
lsr.l #8,Dx
lsr.l #2,Dx

Dx: 00000010

Jak łatwo zauważyć mnożeniu/dzieleniu przez 2-256, odpowiada przesunięcie zawartości rejestru Dx,
o 1-8-bitów w lewo/prawo. Jedna instrukcja LSL/LSR może przesunąć zawartość rejestru Dx, maksy-
malnie o 8-bitów. Jeśli trzeba pomnożyć/podzielić wartość rejestru Dx przez liczbę większą niż 256,
to należy wykonać więcej niż jedną instrukcję LSL/LSR.

Optymalizacja kodu

Optymalizacja rozmiaru, polega na zastępowaniu pewnych instrukcji takimi, które zajmują mniej
bajtów w programie wynikowym po kompilacji kodu, a realizują te same operacje. Oto przykłady:

KOD
ROZMIAR
OPTYMALIZACJA
ROZMIAR
 add.l #$08,Dx
6
 addq.l #8,Dx
2
 sub.l #$08,Dx
6
 subq.l #8,Dx
2
 mulu #$08,Dx
4
 lsl.l #3,Dx
2
 divu #$08,Dx
4
 lsr.l #3,Dx
2
 move.l #$7F000000,Dx 
6
 moveq #$7F,Dx
 ror.l #8,Dx
4
 move.l #$80FFFFFF,Dx
6
 moveq #$80,Dx
 ror.l #8,Dx
4
 move.l #$F0000007,Dx
6
 moveq #$7F,Dx
 ror.l #4,Dx
4
 move.l #$0FFFFFF8,Dx
6
 moveq #$80,Dx
 ror.l #4,Dx
4
 move.l #$007F0000,Dx
6
 moveq #$7F,Dx
 swap Dx
4
 move.l #$FF80FFFF,Dx
6
 moveq #$80,Dx
 swap Dx
4
 add.l #$nn,(Ax)
 tst.b (Ax)
 beq.s X
10
 add.l #$nn,(Ax) 
 beq.s X
8
 sub.l #$nn,(Ax)
 tst.b (Ax)
 beq.s X
10
 sub.l #$nn,(Ax)
 beq.s X
8
 {inst} (Ax)+
 subq.l #1,Ax
 {inst} (Ax)
6
 {inst} (Ax)+
 {inst} -(Ax)
4
 move.l Da,Dx
 move.l Db,Da
 move.l Dx,Db
6
 exg Da,Db
2
 rol.l #8,Dx
 rol.l #8,Dx
4
 swap Dx
2
 ror.l #8,Dx
 ror.l #8,Dx
4
 swap Dx
2

    nn - dowolna wartość szesnastkowa.
{inst} - dowolna instrukcja.

Optymalizacja szybkości działania, polega na zastosowaniu takiego algorytmu, który będzie realizował
określone zadanie używając do tego, jak najmniejszej liczby cykli zegarowych procesora. Prostym
przykładem takiej optymalizacji jest zamiana instrukcji CLR.L Dx (6 cykli) na MOVEQ #0,Dx (4 cykle).

Zatrzymywanie działania programu

Niekiedy zachodzi potrzeba chwilowego zatrzymania działania programu, np. aby przeprowadzić nie-
zbędne operacje przed jego dalszym działaniem. Można też w ten sposób sprawdzić, jakie parametry
(rozmiar stosu, priorytet) posiada program, który znajduje się na liście procesów systemowych.
Oto przykłady:

    st     $aaaaaa
 A: tst.b  $aaaaaa
    bne.s  A
    rts


    sf     $aaaaaa
    rts
        Program START, który należy uruchomić jako pierwszy. Będzie on
działał do momentu uruchomienia programu STOP, znajdującego się
poniżej. Przez ten czas program START będzie widniał na liście
procesów systemowych, co pozwoli odczytać jego parametry.


Program STOP zatrzymuje działanie
programu START, zapisanego wyżej.

Adres $aaaaaa musi wskazywać na komórkę pamięci, nie używaną przez inne programy.

 A: bra.s  A         Taki program raz uruchomiony będzie działał bez końca, aż do wyłączenia
komputera. Zamiast BRA.s A można użyć instrukcji JMP A(pc).
Instrukcja RTS nie jest potrzebna.