Wykonywanie rozkazów
Analizując kody wojowników można się czasem natknąć na instrukcje, których próba interpretacji może przyprawić o ból głowy. Np. taka sekwencja:
DAT $0 $1
start MOV <-1 @-1
...
END start
Wykonanie rozkazu MOV
może dać różne wyniki, zależnie
np. od tego, w którym momencie będzie zmniejszona wartość argumentu
instrukcji DAT
. Aby rozwiać wątpliwości, jakie mogą się
pojawić w podobnych przypadkach, przyjrzyjmy się jak są wykonywane
rozkazy Redcode. Jest to przydatne do analizy cudzych, jak i tworzenia
własnych wojowników.
Sędzia walki, zanim przystąpi do wykonywania rozkazu, zapamiętuje go w specjalnym rejestrze. Oznacza to, że treść rozkazu nie może ulec zmianie w trakcie wykonywania.
Kolejnym krokiem jest opracowanie argumentów rozkazu. Polega ono na
wyznaczeniu adresów argumentów A
i B
oraz na
wyciągnięciu spod tych adresów dwóch par wartości tamtejszych
argumentów. Bardzo ważną zasadą jest niezmienianie zawartości rdzenia aż
do wyznaczenia wszystkich adresów i wszystkich wartości. Konsekwencją
tej zasdy jest fakt, iż podczas wyznaczania adresu argumentu typu
<
sędzia nie od razu zmienia zawartość rdzenia. Najpierw
adres jest liczony jak dla typu @
, z tym, ze końcowy wynik
jest zmniejszany o jeden. Dopiero po całkowitym opracowaniu obu
argumentów sędzia odszukuje na rdzeniu odpowiednią komórkę i zmniejsza
jej zawartość (a dokłądnie wartość pola argumentu B
) o
jeden. Gdyby oba argumenty były typu <
, zmniejszona
byłaby zawartość dwóch komórek, a gdyby wskazywały one na tę samą
komórkę, jej zawartość byłaby zmniejszona o dwa.
Po przygotowaniu obu argumentów sędzia wykonuje rozkaz, oraz, jeśli nie był to skok, zwiększa licznik programu (program counter) o jeden, aby wskazywał kolejną instrukcję. Potem sędzia odczytuje licznik następnego procesu (jeśli program jest wieloprocesowy), przepisuje do specjalnego rejestru kolejny rozkaz i wszystko zaczyna się od początku.
Po takiej dawce teorii mozemy się zabrać za analizę powyższej sekwencji. Z łatwością wyznaczymy faktyczne adresy argumentów:
A-adres = -1
B-adres = 0
Ponieważ argument A
rozkazu MOV
nie jest
typu #
, rozkaz operuje tylko na adresach argumentów i nie
interesują nas ich wartości. Sędzie po opracowaniu obu argumentów
zmniejszy argument instrukcji DAT
o jeden, i w ramach
wykonania rozkazu, przeniesie instrukcję DAT $0 $0
w
miejsce instrukcji MOV
. Możemy się o tym przekonać w
debuggerze WOJOWNIKA.
Przeanalizujmy teraz kolejny przykład:
DAT <0 <2
start DJN @-1 $-1
SPL $-2
JMP $0
END start
Zaczynamy od wyznaczenia adresów argumentów rozkazu
DJN
:
A-adres = 1
B-adres = -1
Wykonanie rozkazu zmniejszy B-adres-B-wartość
z 2 do 1 i
ponieważ będzie ona różna od zera, spowoduje skok pod
A-adres
, czyli do rozkazu SPL
. Tutaj widzimy,
jak ważna jest konieczność wyznaczania wszystkich adresów i wartości
argumentów przed wykonaniem rozkazu. Gdyby sędzie wyznaczył
A-adres
nie od razu, a dopiero po stwierdzeniu, że należy
wykonać skok (a zatem także i po wykonaniu rozkazu DJN
),
jego wartość byłaby już inna A-adres = 0
(wartość
błędna).
Kolejny rozkazem jest SPL
. Wykonanie go spowoduje
uruchomienie równoległego procesu od adresu A-adres
, czyli
od rozkazu DAT
. Teraz próba wykonania rozkazu
DAT
spowoduje śmierć procesu potomnego, podczas gdy proces
macierzysty zapętli się wykonując bez końca rozkaz JMP
.
Operacje te są konieczne, aby móc w debuggerze WOJOWNIKA
zobaczyć efekt wykonania rozkazu DAT
.
Zgodnie z przyjętą zasadą sędzia najpierw wyznacza adresy i wartości
argumentów, następnie, jeśli wystąpiły argumenty typu <
,
zmniejsza B-wartość
odpowiednich komórek, a dopiero na
końcu wykonuje rozkaz. W konsekwencji wykonanie rozkazu
DAT <0 <1
zmniejszy B-wartości
komórek o
adresach 0 (instrukcja DAT
) i 1 (instrukcja
DJN
). Arena będzie zatem wyglądała tak:
DAT <0 <0
start DJN @-1 $-2
SPL $-2
JMP $0 ; tu uwięziony jest proces macierzysty
Tekst ten jest niejako uzupełnieniem artykułu A. Stasiewicza „Kowboj, Ferret i inni wojownicy” (ENTER 2/92 i 3/92). Miłośnicy Wojen Rdzeniowych znajdą tam opis języka Redcode wraz z krótkim kursem programowania.
Na stronie 151-152 tego numeru przedstawiamy nowe środowiska do rozgrywania Wojen Rdzeniowych. Następcą WOJOWNIKA został program Arbiter. Ponieważ Mistrzostwa Polski będą rozegrane w nowym środowisku, odbędą się one później niż zapowiadałem. Termin wstępnie przesunęliśmy na marzec, aby wszyscy zainteresowani zdążyli zakupić nowe oprogramowanie i poznać je. O dokładnym terminie poinformujemy, a mnie pozostaje przeprosić Czytelników za błędne informacje.