EMAS: Różnice pomiędzy wersjami

Przejdź do nawigacji Przejdź do wyszukiwania
Dodane 4710 bajtów ,  26 lut 2016
Nie podano opisu zmian
(Nie pokazano 24 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 1: Linia 1:
EMAS jest assemblerem skrośnym dla MERRY 400, używającym, w odróżnieniu od [[ASSEM]], składni bliższej współczesnym assemblerom, oraz mnemoników MERY 400 (ale bez przyrostków zależnych od lokalizacji argumentu, patrz: [[Lista rozkazów]]).
EMAS jest assemblerem skrośnym dla MERRY 400, używającym, w odróżnieniu od [[ASSEM]], składni bliższej współczesnym assemblerom, oraz mnemoników MERY 400 (ale bez przyrostków zależnych od lokalizacji argumentu, patrz: [[Lista rozkazów]]).
Repozytorium źródeł EMAS: https://github.com/jakubfi/emas


= Wywołanie =
= Wywołanie =
Linia 5: Linia 7:
Wywołanie EMAS z linii poleceń ma postać:
Wywołanie EMAS z linii poleceń ma postać:


emas [opcje] [wejście [wyjście]]
emas [opcje] [wejście]


Gdzie:
Gdzie:


* '''wejście''' - nazwa wejściowego pliku źródłowego. Jeśli nie zostanie podana, EMAS czyta program ze standardowego wejścia, a wyjściem staje się plik ''out.bin''
* '''wejście''' - nazwa wejściowego pliku źródłowego. Jeśli nie zostanie podana, EMAS czyta program ze standardowego wejścia
* '''wyjście''' - nazwa wyjściowego pliku binarnego. Jeśli nie zostanie podana, przyjmowana jest nazwa ''out.bin''
* '''opcje''' - dowolne z:
* '''opcje''' - dowolne z:
** '''-o <wyjście>''' - nazwa wyjściowego pliku binarnego. Jeśli nie zostanie podana, przyjmowana jest nazwa ''a.out''
** '''-O <otype>''' - typ pliku wyjściowego. Możliwe wybory to:
*** ''raw'' - binarny obraz gotowy do umieszczenia w pamięci i uruchomienia
*** ''debug'' - plik tekstowy opisujący zawartość kolejnych komórek pamięci (przydatny w przypadku programowania komputera z pulpitu technicznego)
*** ''emelf'' - konsolidowalny obiekt [[EMELF]] (domyślny wybór)
** '''-c <cpu>''' - wybierz procesor, dla jakiego assembler produkuje binaria. Możliwe wybory to: ''mera400'', ''mx16''. Ustawienie procesora na MX-16 pozwala na użycie dodatkowych instrukcji oraz poszerza przestrzeń adresową programu z 32 do 64k słów. Domyślnie przyjmowany procesor to ''mera400''.
** '''-c <cpu>''' - wybierz procesor, dla jakiego assembler produkuje binaria. Możliwe wybory to: ''mera400'', ''mx16''. Ustawienie procesora na MX-16 pozwala na użycie dodatkowych instrukcji oraz poszerza przestrzeń adresową programu z 32 do 64k słów. Domyślnie przyjmowany procesor to ''mera400''.
** '''-O <otype>''' - wybierz typ pliku wyjściowego. Możliwe wybory to:
*** ''raw'' - binarny obraz gotowy do umieszczenia w pamięci i uruchomienia (domyślny wybór)
*** ''debug'' - plik tekstowy opisujący zawartość kolejnych komórek pamięci (przydatny w przypadku programowania komputera z pulpitu technicznego)
*** ''emelf'' - obiekt dla konsolidatora (opcja nie zaimplementowana)
** '''-I <katalog>''' - dodaj katalog do listy katalogów, w których poszukiwane będą pliki dołączane dyrektywą .include
** '''-I <katalog>''' - dodaj katalog do listy katalogów, w których poszukiwane będą pliki dołączane dyrektywą .include
** '''-v''' - wyświetl informacje o wersji i zakończ działanie
** '''-v''' - wyświetl informacje o wersji i zakończ działanie
** '''-h''' - wyświetl pomoc i zakończ działanie
** '''-h''' - wyświetl pomoc i zakończ działanie
** '''-d''' - drukuj informacje przydatne w śledzeniu błędów działania asemblera


= Opis języka =
= Opis języka =
Linia 53: Linia 56:
  ?GVZ
  ?GVZ


EMAS przechowuje liczby całkowite jako 32-bit liczby w kodzie U2 i na takich liczbach operuje. W trakcie umieszczania liczb w obiekcie wynikowym są one obcinane do 16 najmłodszych bitów. Wyjątkiem jest argument dyrektywy '''.dword''', który jest 32-bit liczbą w kodzie U2.
Wewnętrznie EMAS operuje na 32-bit liczbach ze znakiem. Kiedy ostateczna wartość będąca wynikiem operacji ma zostać umieszczona w obiekcie wynikowym, jej zakres jest sprawdzany i użytkownik jest informowany o ewentualnym jego przekroczeniu. Wyjątkiem jest argument dyrektywy '''.dword''', który jest 32-bit liczbą w kodzie U2.
 
=== Znaki ===
 
EMAS pozwala na zapisywanie stałych całkowitoliczbowych również przy pomocy znaków, dwuznaków lub trójznaków. Znaki pojedyncze oraz dwuznaki obejmują cały zakres znaków ASCII i można je podawać również używając sekwencji unikowych. Trójznaki pozwalają kodować jedynie znaki poprawne dla [[CROOK-5 - Interpretator zleceń użytkownika - XOSL#Kod R40|kodu R40]].
 
Znaki w pojedynczych cudzysłowach:
 
'a', '\n', '\xa1', '\0177'
 
kodowane są jako ich wartość w kodzie ASCII na młodszym bajcie słowa. Dwuznaki:
 
'ab', '\r\n', '\xaa\0001'
 
kodowane są jako wartości podanych znaków w kodzie ASCII odpowiednio na starszym i młodszym bajcie słowa. Trójznaki:
 
'abc', 'XYZ', '#_1'
 
kodowane są w słowie za pomocą [[CROOK-5 - Interpretator zleceń użytkownika - XOSL#Kod R40|kodu R40]].


=== Liczby zmiennoprzecinkowe ===
=== Liczby zmiennoprzecinkowe ===
Linia 69: Linia 90:
=== Łańcuchy ===
=== Łańcuchy ===


Łańcuchy znaków są ciągami 8-bit znaków ujętymi w podwójne cudzysłowy. Poszczególne znaki można zapisywać dosłownie, lub używając jednej z sekwencji unikowych:
Łańcuchy znaków są ciągami znaków ujętymi w podwójne cudzysłowy. Poszczególne znaki można zapisywać dosłownie, lub (w przypadku dyrektyw '''.ascii''' i '''.asciiz''') używając jednej z sekwencji unikowych:
 
* \0'''yyy''' - gdzie '''yyy''' jest ósemkowym kodem znaku
* \0'''yyy''' - gdzie '''yyy''' jest ósemkowym kodem znaku
* \x'''yy''' - gdzie '''yy''' jest szesnastkowym kodem znaku
* \x'''yy''' - gdzie '''yy''' jest szesnastkowym kodem znaku
Linia 86: Linia 108:
  "\"napis\""
  "\"napis\""


Umieszczając łańcuchy w programie wynikowym EMAS lokuje każde dwa kolejne sąsiadujące ze sobą znaki kolejno w starszej i młodszej połówce 16-bit słowa. Jeśli łańcuch zawiera nieparzystą liczbę znaków, to w ostatnim słowie na pozycji młodszego bajtu znajdzie się wartość 0.
To, w jaki sposób znaki umieszczane są w programie wynikowym zależy od dyrektywy, której łańcuch jest argumentem.
 
=== Bieżąca lokalizacja ===
 
Specjalną stałą jest "." (kropka), która w danym miejscu programu zawsze zwraca przesunięcie względem początku assemblowanego obiektu. Jej wartość jest zawsze >= 0.


== Symbole ==
== Symbole ==


Symbolem jest ciąg znaków zaczynający się od małej lub dużej litery, z następującą dowolną ilością małych lub dużych liter, liczb lub znaku podkreślenia.
Symbolem jest ciąg znaków zaczynający się od małej lub dużej litery, z następującą dowolną ilością małych lub dużych liter, liczb lub znaku podkreślenia.
Symbolowi przypisywana jest wartość liczbowa oraz atrybuty. Symbol może być:
Symbolowi przypisywana jest w trakcie asemblacji wartość oraz atrybuty. Symbol może być:


* niezdefiniowany - wystąpiła deklaracja symbolu, ale nie został on (jeszcze) zdefiniowany,
* niezdefiniowany - wystąpiła deklaracja symbolu, ale nie został on (jeszcze) zdefiniowany,
* względny lub bezwzględny - wartością symbolu jest adres, który może zmienić się w procesie konsolidacji, bądź niezmienna wartość liczbowa,
* lokalny lub globalny - widoczny tylko w granicach obiektu, w którym występuje, bądź również poza nim,
* lokalny lub globalny - widoczny tylko w granicach obiektu, w którym występuje, bądź również poza nim,
* zmienny lub stały - wartość symbolu może, bądź nie może ulec zmianie w trakcie asemblacji programu.
* zmienny lub stały - wartość symbolu może, bądź nie może ulec zmianie w trakcie asemblacji programu.
Linia 102: Linia 127:
=== Zmienne assemblera ===
=== Zmienne assemblera ===


Zmienne assemblera nie mają swojej reprezentacji w wynikowym obiekcie, są wartościami dostępnymi w trakcie asemblacji programu, a definiuje się je dyrektywą '''.equ'''. Symbol, który jest zmienną assemblera jest zawsze bezwzględny i zmienny. Przykłady zmiennych:
Zmienne assemblera nie mają swojej reprezentacji w wynikowym obiekcie, są wartościami dostępnymi w trakcie asemblacji programu, a definiuje się je dyrektywą '''.equ'''. Symbol, który jest zmienną assemblera jest zawsze zmienny. Przykłady zmiennych:


  .equ a 10
  .equ a 10
Linia 109: Linia 134:
=== Stałe assemblera ===
=== Stałe assemblera ===


Stałe assemblera również nie mają swojej reprezentacji w wynikowym obiekcie, są wartościami dostępnymi w trakcie asemblacji programu, a definiuje się je dyrektywą '''.const'''. Symbol, który jest zmienną assemblera jest zawsze bezwzględny i stały. Przykłady stałych:
Stałe assemblera również nie mają swojej reprezentacji w wynikowym obiekcie, są wartościami dostępnymi w trakcie asemblacji programu, a definiuje się je dyrektywą '''.const'''. Symbol, który jest zmienną assemblera jest zawsze stały. Przykłady stałych:


  .const a 10
  .const a 10
Linia 116: Linia 141:
=== Etykiety ===
=== Etykiety ===


Etykieta jest zawsze stałym symbolem względnym i zawiera pozycję względem początku obiektu, czyli wartość licznika rozkazów w danym momencie asemblacji. Przykład definicji etykiety:
Etykieta opisuje pozycję względem początku obiektu (jest nią wartość licznika rozkazów w danym momencie asemblacji). Przykład definicji etykiety:


  etykieta:
  etykieta:
Linia 122: Linia 147:
=== Zasięg symboli ===
=== Zasięg symboli ===


Wszystkie symbole definiowane są jako lokalne. Jeśli symbol ma być widoczny dla konsolidatora, należy go zadeklarować jako globalny dyrektywą '''.global'''. Globalne mogą być wyłącznie symbole względne (etykiety), a zmiana zasięgu może nastąpić przed, lub po definicji:
Wszystkie symbole definiowane są jako lokalne. Jeśli symbol ma być widoczny dla konsolidatora, należy go zadeklarować jako globalny dyrektywą '''.global'''. Zmiana zasięgu może nastąpić przed, lub po definicji:


  .global printf
  .global printf
  .global snprintf
  .global snprintf
  .global strdup
  .global strdup
 
  printf:
  printf:
  ...
  ...
Linia 133: Linia 158:
  ...
  ...
  strdup:
  strdup:
 
  procedura:
  procedura:
  .global procedura
  .global procedura


=== Punkt wejścia ===
== Wyrażenia ==


Symbolem o specjalnym znaczeniu jest punkt wejścia, deklarowany dyrektywą '''.entry'''. Jego wartością jest adres, od którego program zostanie uruchomiony (ma to znaczenie tylko gdy obiektem wyjściowym jest emelf). Z tego powodu, podobnie jak w przypadku symboli globalnych, punktem wejścia może być tylko symbol względny. W przypadku źródła, które zawiera kod przeznaczony do umieszczenia w bloku pamięci systemu operacyjnego (dyrektywa '''.os'''), punkt wejścia ustawiany jest automatycznie na wartość 0.
=== Operatory ===


== Wyrażenia ==
Poniższa tabela przedstawia operatory arytmetyczne i bitowe, w kolejności malejących priorytetów
 
{| class="wikitable"
! Operatory !! Działanie
|-
| ~ || negacja bitowa
|-
| \ || skalowanie
|-
| *, /, % || mnożenie, dzielenie, reszta z dzielenia
|-
| +, - || dodawanie, odejmowanie
|-
| <<, >> || przesunięcie bitowe w lewo i w prawo
|-
| &, <nowiki>|</nowiki>, ^ || logiczny iloczyn, suma i suma wykluczająca
|}
 
Operator skalowania realizuje funkcję dokładnie taką samą, jak przesunięcie bitowe, jest tylko innym sposobem jego zapisu. Poniższe zapisy są równoznaczne:
 
3\7  = 3 << (15-7)
 
Skalowanie można rozumieć jako: "umieść liczbę 3 od 7 pozycji bitowej w górę. Bity dla tego zapisu numerowane są od 0 (bit najstarszy) do 15 (bit najmłodszy). Wynikiem będzie więc liczba:
 
0000001100000000


== Dyrektywy assemblera ==
== Dyrektywy assemblera ==
=== .cpu ===
'''Składnia:''' .cpu <mera400|mx16>
Odpowiednik przełącznika ''-c'' linii poleceń EMAS-a. Pozwala określić typ procesora, dla którego ma być generowany kod wynikowy. Użycie ''mx16'' sprawia, że:
* mnemoniki '''CRON''', '''SINT''', '''SIND''' są rozpoznawane i poprawnie assemblowane
* maksymalny rozmiar wynikowego pliku binarnego wynosi 64k słowa (32k dla ''mera400'')
=== .file ===
'''Składnia:''' .file ''nazwa_pliku''
Ustala nazwę assemblowanego pliku. Jeśli assembler będzie chciał użyć w komunikatach nazwy pliku, to domyślna nazwa (zgodna z nazwą assemblowanego pliku) zostanie od momentu wydania dyrektywy zastąpiona podaną.
=== .line ===
'''Składnia:''' .line ''numer_linii''
Ustala numer bieżącej linii assemblacji (poczynając od linii następującej po dyrektywie). Dalsze linie będą numerowane kolejno od podanej wartości.
=== .include ===
'''Składnia:''' .include ''nazwa_pliku''
Powoduje dołączenie do assemblacji pliku o podanej nazwie.
=== .equ ===
'''Składnia:''' .equ ''nazwa_zmiennej'' ''wartość''
Ustala wartość zmiennej assemblacji. Może być ona w dalszej części programu zmieniana.
=== .const ===
'''Składnia:''' .const ''nazwa_zmiennej'' ''wartość''
Ustala wartość stałej assemblacji. Wartość ta nie może ulec zmianie.
=== .lbyte ===
'''Składnia:''' .lbyte ''liczba_8_bit'' [, ...]
Zapisuje w programie wynikowym na lewych pozycjach (MSB) kolejnych słów podane wartośći 8-bit.
=== .rbyte ===
'''Składnia:''' .rbyte ''liczba_8_bit'' [, ...]
Zapisuje w programie wynikowym na prawych pozycjach (LSB) kolejnych słów podane wartośći 8-bit.
=== .word ===
'''Składnia:''' .word ''liczba_16_bit'' [, ...]
Zapisuje w programie kolejne słowa 16-bit o podanej wartości.
=== .dword ===
'''Składnia:''' .dword ''liczba_32_bit'' [, ...]
Zapisuje w programie wynikowym pary słów 16-bit tworzące podaną liczbę 32-bit.
=== .float ===
'''Składnia:''' .float ''liczba_zmiennoprzecinkowa'' [, ...]
Zapisuje w programie wynikowym trójki słów 16-bit tworzące podaną 48-bit liczbę zmiennoprzecinkową w notacji używanej przez arytmometr wielokrotnej precyzji MERY-400.
=== .ascii ===
'''Składnia:''' .ascii ''łańcuch''
Zapisuje w programie wynikowym podany łańcuch, kodując go po dwa znaki ASCII na słowo maszynowe.
=== .asciiz ===
'''Składnia:''' .asciiz ''łańcuch''
Zapisuje w programie wynikowym podany łańcuch, kodując go po dwa znaki ASCII na słowo maszynowe. Łańcuch terminowany jest 8-bit wartością '0'.
=== .r40 ===
'''Składnia:''' .r40 ''łańcuch_r40''
Zapisuje w programie wynikowym podany łańcuch, kodując go po trzy znaki R40 na słowo maszynowe. '''UWAGA:''' W kodzie R40 można użyuwać jedynie liter, liczb i znaków specjalnych: _, #, %.
=== .res ===
'''Składnia:''' .res ''rozmiar'' [,''liczba_16_bit'']
Rezerwuje w programie wynikowym obszar o podanym rozmiarze (w słowach), wypełniając go zerami. Jeśli podany jest drugi argument, jego wartość używana jest do wypełnienia zamiast zera.
=== .org ===
'''Składnia:''' .org ''adres''
Ustala nową bieżącą pozycję assemblacji. Następne wygenerowane słowo zostanie umieszczone już pod podanym, nowym adresem.
=== .entry ===
'''Składnia:''' .entry ''adres''
Dyrektywa ma efekt wyłącznie w przypadku generowania pliku wynikowego jako obiektu EMELF. Określa adres wejścia do programu.
=== .global ===
'''Składnia:''' .global ''nazwa_etykiety''
Dyrektywa ma efekt wyłącznie w przypadku generowania pliku wynikowego jako obiektu EMELF. Wskazuje, że etykieta będzie miała zasięg globalny.


== Rozkazy ==
== Rozkazy ==

Menu nawigacyjne