[ASM] Kompilator na I8080/I8085

Kącik dla elektroniki retro - układy, urządzenia, podzespoły, literatura itp.
Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

[ASM] Kompilator na I8080/I8085

Postautor: gaweł » sobota 30 lip 2022, 23:33

Kompilator asm dla I8080/I8085

c8080_00.png


Trochę na fali zainteresowania klasycznymi procesorami, trochę z powodu własnej potrzeby, powstało oprogramowania do tworzenia programów na klasyczne mikroprocesory. Moja historia zainteresowania mikroprocesorami jest prawie tak stara jak same mikroprocesory. W latach 80-tych XX wieku zaczęły przenikać do naszego kraju same układy. Na sławetnym volumenie dawało się nabyć układy szmuglowane z zagranicy. Do budowy komputerów oprócz układów niezbędne jest jeszcze oprogramowanie narzędziowe. Z tym było trochę gorzej, gdyż warto pamiętać, że era kompów PC dopiera wchodziła do naszego kraju i właściwie poza uczelnią nie dawało się korzystać z takiego wsparcia.
Skoro nie było kompów, to również nie było szmuglu samego oprogramowania. Pierwsze potyczki z prockami bazowały na ręcznym kompilowaniu programów. Ćwiczyło to w jakiś sposób pamięć, bo kody najczęściej stosowanych instrukcji były w małym paluszku. Później zaczęły pojawiać się sprzęty typu SPECTRUM. Było to już jakieś lepsze wsparcie.
Jednak ja podążyłem własną drogą i posiłkowałem się politechniczną oderką. Do tego kompa miałem nieograniczony dostęp więc szybko zacząłem tworzyć na oderce własne kompilatory. To rozwiązanie miało jedną wadę: zawartość pamięci EPROM trzeba było przeklepać z wydruku. Z czasem pojawiły się na polibudzie pierwsze PC-ty, więc nastąpił transfer technologii do nowego środowiska. Na oderce typowo stosowałem PASCAL, na PC-tach TURBOPASCAL, więc w większości przypadków dużych problemów nie było z przeprowadzką. Studencki kolega w ramach pracy dyplomowej popełnił kompiler PASCAL'a na Z80, który na oderce nawet działał, ale przeniesiony na PC-ta przestał. Program był duży, a TP w wersji 3 generowało pliki typu COM, więc trzeba było stosować triki z nakładkami, ale jak się okazało, to słabo działało.
No ale... wracając do asmów...
W tamtych czasach nie było internetu, więc takie informacje jak lista instrukcji czy kody instrukcji trzeba było jakoś zdobywać. Tak się jakoś fajnie złożyło, że miałem dostęp do takiej książki:
c8080_01.png

Dzisiaj to ją nawet ściągnąłem (bardziej chyba z sentymentu niż z rzeczywistej potrzeby). Była ona ogromnie pomocna, gdyż moim pierwszym prockiem jaki miałem w rękach był MC6800. Był taki ładny. Miał obudowę ceramiczną we filetowym kolorze ze złotym dekielkiem. Na jego temat to literatura w języku polskim nawet dzisiaj jest dosyć skromna (by nie powiedzieć, że praktycznie nie istnieje). Kompilator napisać to nie jest jakiś wielki problem, dostęp do rzetelnej wiedzy, to już jest problem. Więc lista instrukcji → książka Osborna.
Potem moje zainteresowania skupiły się nad czymś innym, więc stare kompilery (napisałem ich na kilka procków) poszły do archiwum, by po jakimś czasie ponownie znaleźć się o w obszarze zainteresowania. Wiadomo, technika się rozwija, toteż stary soft przeszedł poważną rewitalizację i dzisiaj uważam, że nada się do użytku.
Jako wsparcie poszukującym narzędzi do programowania mikroprocesora I8080/I8085 mogę zaproponować własne rozwiązanie. Jak wcześniej wspomniałem, powstało ono w dosyć zamierzchłych czasach, by ostatnio ponownie przeżyć swoje 5 minut. Jak zwykle, powstało z potrzeby chwili (tak jak teraz, gdyż od jakiegoś czasu chodzi mi po głowie pewna koncepcja uratowania przed śmiercią na śmietniku kilku procesorów, a przy okazji inni użytkownicy mają wsparcie).
Podstawowa wiedza dotycząca proca I8080 powinna być znana, ale pozwolę sobie napisać trochę na temat tego procka. To może dla niektórych być dosyć nowym doświadczeniem, dla innych spowodować swoistą podróż do tych niezwykłych czasów, gdy te procki były na topie. Postarajmy się pogrzebać we własnej głowie i wydobyć informacje na wierzch.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 00:01

Kompilator asm dla I8080/I8085

Kompilator jest utworzony w środowisku Lazarus i jest oprogramowaniem nie wymagającym jakiejkolwiek licencji. Może nie jest to jakieś super narzędzie, gdyż nie wykonuje linkowania niezależnie kompilowanych kawałków. Jego użycie sprowadza się do wskazania pliku do kompilacji, który musi zawierać kompletne oprogramowanie w formie źródłowej, chociaż pliki mogą być podzielone na kilka kawałków. Program obsługuje zaklęcie include, które dołącza do kompletu jakiś kawałek całości, choć skrajnie całość może składać się z jednego kawałka. W dołączanych plikach (przez include) mogą być kolejne pliki dołączane tym samym zaklęciem, jednak sytuacja rekurencyjnie zapętlonego include jest wykrywana i traktowana jako błąd kompilacji (nie jest wtedy generowany kod dla procka).
c8081_01.PNG

Najprostsze użycie programu, to jest uruchomić go i tak go pozostawić. Program źródłowy można edytować w dowolnym edytorze (może być NOTATNIK) i po zapisaniu zmian na dysku, myszką uchwycić nazwę pliku, przeciągnąć i upuścić na formę kompilatora. Spowoduje to otwarcie pliku i jego kompilację. Zawsze powstaje raport z kompilacji oraz jeżeli nie było błędów kompilacji, to powstaje plik w formacie Intel-hex, o czym informuje odpowiedni komunikat.
c8081_02.PNG

W przypadku błędnej kompilacji, nie powstaje plik dla procka, o czym informuje program.
c8081_03.PNG

Każde nowe upuszczenie nazwy pliku na formę kompilatora uruchamia proces kompilacji. Ten sam efekt można uzyskać po wyklikaniu nazwy pliku po użyciu przycisku „Open source”.
Zaklęcie include ma następującą składnię (wszystkie dyrektywy zaczynają się od znaku kropki):
.include 'nazwa pliku'
Przykład kompilacji następującego programu:

Kod: Zaznacz cały

;
;  ***************************************************
;  *                                                 *
;  *                                                 *
;  *    zbior instrukcji mikroprocesora 8080         *
;  *                                                 *
;  *                                                 *
;  ***************************************************
;
.include 't8080.asm'
;
;

Generuje następujący raport:
c80801_04.png

Raport z kompilacji zawiera następujące informacje:
c80801_05.png


Kompiler:
I8080.7z

Użyte przykłady:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 00:34

Lista instrukcji mikroprocesora
i8080/i8085


Zestaw rejestrów mikroprocesora I8080/I8085.
c80802_01.png

W instrukcjach występuje „pseudo rejestr” określany jako M będący komórką pamięci o adresie zawartym w parze rejestrów HL.

I. Grupa instrukcji wejścia/wyjścia

  • IN port – wczytaj do akumulatora A bajt z urządzenia o adresie port
    [A] ← [port]
  • OUT port – wyślij z akumulatora A bajt do urządzenia o adresie port
    [port] ← [A]

II. Grupa instrukcji przesłania danych 8-bitowych

  • MOV reg1,reg2 – przepisz zawartość rejestru reg2 do rejestru reg1
    [reg1] ← [reg2]
  • MOV reg,M – przepisz do rejestru reg zawartość bajtu pamięci o adresie zawartym w parze rejestrów HL
    [reg] ← [[HL]]
  • MOV M,reg – przepisz do bajtu pamięci o adresie zawartym w parze rejestrów HL zawartość rejestru reg
    [[HL]] ← [reg]
  • MVI reg,data8 – wpisz do rejestru reg wartość data8
    [reg] ← data8
  • MVI M,data8 – wpisz do bajtu pamięci o adresie zawartym w parze rejestrów HL wartość data8
    [[HL]] ← data8
  • LDAX B – przepisz do akumulatora A zawartość bajtu pamięci o adresie zawartym w parze rejestrów BC
    [A] ← [BC]
  • LDAX D – przepisz do akumulatora A zawartość bajtu pamięci o adresie zawartym w parze rejestrów DE
    [A] ← [DE]
  • STAX B – składuj zawartość akumulatora A w pamięci operacyjnej o adresie określonym zawartością pary rejestrów BC
    [BC] ← [A]
  • STAX D – składuj zawartość akumulatora A w pamięci operacyjnej o adresie określonym zawartością pary rejestrów DE
    [DE] ← [A]
  • LDA adr16 – wpisz do akumulatora A zawartość bajtu pamięci o adresie określonym przez adr16
    [A] ← [adr16]
  • STA adr16 – składuj zawartość akumulatora A w pamięci o adresie określonym przez adr16
    [adr16] ← [A]

III. Grupa instrukcji przesłania danych 16-bitowych

  • LHLD adr16 – wpisz do pary rejestrów HL zawartość słowa pamięci operacyjnej o adresie określonym przez adr16
    [HL] ← [adr16]
  • SHLD adr16 – składuj zawartość pary rejestrów HL w słowie pamięci operacyjnej o adresie określonym przez adr16
    [adr16] ← [HL]
  • LXI B,data16 – wpisz do pary rejestrów BC wartość data16
    [BC] ← data16
  • LXI D,data16 – wpisz do pary rejestrów DE wartość data16
    [DE] ← data16
  • LXI H,data16 – wpisz do pary rejestrów HL wartość data16
    [HL] ← data16
  • LXI SP,data16 – wpisz do rejestru SP wartość data16
    [SP] ← data16
  • XCHG – wymień zawartości par rejestrów HL i DE miedzy sobą
    [HL] ↔ [DE]
  • SPHL – przepisz zawartość pary rejestrów HL do rejestru SP
    [SP] ← [HL]
  • XTHL – wymień zawartości pary rejestrów HL i szczytu stosu miedzy sobą
    [HL] ↔ [[SP]]
  • SPHL – przepisz zawartość pary rejestrów HL do rejestru SP
    [SP] ← [HL]
  • PUSH B – wpisz na szczyt stosu zawartość pary rejestrów BC
    [[SP]] ← [BC]
    [SP] ← [SP]-2
  • PUSH D – wpisz na szczyt stosu zawartość pary rejestrów DE
    [[SP]] ← [DE]
    [SP] ← [SP]-2
  • PUSH H – wpisz na szczyt stosu zawartość pary rejestrów HL
    [[SP]] ← [HL]
    [SP] ← [SP]-2
  • PUSH PSW – wpisz na szczyt stosu zawartość słowa statusowego (PSW – akumulator i wskaźniki)
    [[SP]] ← [PSW]
    [SP] ← [SP]-2
  • POP B – pobierz ze szczytu stosu zawartość pary rejestrów BC
    [BC] ← [[SP]]
    [SP] ← [SP]+2
  • POP D – pobierz ze szczytu stosu zawartość pary rejestrów DE
    [DE] ← [[SP]]
    [SP] ← [SP]+2
  • POP H – pobierz ze szczytu stosu zawartość pary rejestrów HL
    [HL] ← [[SP]]
    [SP] ← [SP]+2
  • POP PSW – pobierz ze szczytu stosu zawartość słowa statusowego (PSW – akumulator i wskaźniki)
    [PSW] ← [[SP]]
    [SP] ← [SP]+2

IV. Grupa instrukcji operacji arytmetycznych i logicznych danych 8-bitowych

  • ADD reg – dodaj do zawartości akumulatora A zawartość rejestru reg
    [A] ← [A]+[reg]
  • ADD M – dodaj do zawartości akumulatora A zawartość bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL
    [A] ← [A]+[[HL]]
  • ADI data8 – dodaj do zawartości akumulatora A wartość data8
    [A] ← [A]+data8
  • ADC reg – dodaj do zawartości akumulatora A zawartość rejestru reg z uwzględnieniem bitu przeniesienia C
    [A] ← [A]+[reg]+C
  • ADC M – dodaj do zawartości akumulatora A zawartość bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL z uwzględnieniem bitu przeniesienia C
    [A] ← [A]+[[HL]]+C
  • ACI data8 – dodaj do zawartości akumulatora A wartość data8 z uwzględnieniem bitu przeniesienia C
    [A] ← [A]+data8+C
  • SUB reg – odejmij od zawartości akumulatora A zawartość rejestru reg
    [A] ← [A]-[reg]
  • SUB M – odejmij od zawartości akumulatora A zawartość bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL
    [A] ← [A]-[[HL]]
  • SUI data8 – odejmij od zawartości akumulatora A wartość data8
    [A] ← [A]-data8
  • SBB reg – odejmij od zawartości akumulatora A zawartość rejestru reg z uwzględnieniem bitu przeniesienia C
    [A] ← [A]-[reg]-C
  • SBB M – odejmij od zawartości akumulatora A zawartość bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL z uwzględnieniem bitu przeniesienia C
    [A] ← [A]-[[HL]]-C
  • SBI data8 – odejmij od zawartości akumulatora A wartość data8 z uwzględnieniem bitu przeniesienia C
    [A] ← [A]-data8-C
  • ANA reg – wykonaj iloczyn logiczny zawartości akumulatora A i zawartości rejestru reg
    [A] ← [A] AND [reg]
  • ANA M – wykonaj iloczyn logiczny zawartości akumulatora A i zawartości bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL
    [A] ← [A] AND [[HL]]
  • ANI data8 – wykonaj iloczyn logiczny zawartości akumulatora A i wartości data8
    [A] ← [A] AND data8
  • ORA reg – wykonaj sumę logiczną zawartości akumulatora A i zawartości rejestru reg
    [A] ← [A] OR [reg]
  • ORA M – wykonaj sumę logiczną zawartości akumulatora A i zawartości bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL
    [A] ← [A] OR [[HL]]
  • ORI data8 – wykonaj sumę logiczną zawartości akumulatora A i wartości data8
    [A] ← [A] OR data8
  • XRA reg – wykonaj sumę logiczną EXOR zawartości akumulatora A i zawartości rejestru reg
    [A] ← [A] XOR [reg]
  • XRA M – wykonaj sumę logiczną EXOR zawartości akumulatora A i zawartości bajtu pamięci o adresie określonym przez zawartość pary rejestrów HL
    [A] ← [A] XOR [[HL]]
  • XRI data8 – wykonaj sumę logiczną EXOR zawartości akumulatora A i wartości data8
    [A] ← [A] XOR data8
  • CMP reg – wykonaj porównanie (ustaw tylko wskaźniki) zawartości akumulatora A i zawartości rejestru reg
    [A] – [reg]
  • CMP M – wykonaj porównanie (ustaw tylko wskaźniki) zawartości akumulatora A i zawartości bajtu pamięci o adresie określonym przez zawartość pary rejestrówHL
    [A] – [[HL]]
  • CPI data8 – wykonaj porównanie (ustaw tylko wskaźniki) zawartości akumulatora A i wartości data8
    [A] – data8
  • INR reg – zwiększ zawartość rejestru reg o jeden
    [reg] ← [reg]+1
  • INR M – zwiększ zawartość bajtu pamięci o adresie zawartym z parze rejestrów HL o jeden
    [[HL]] ← [[HL]]+1
  • DCR reg – zmniejsz zawartość rejestru reg o jeden
    [reg] ← [reg]-1
  • DCR M – zmniejsz zawartość bajtu pamięci o adresie zawartym z parze rejestrów HL
    [[HL]] ← [[HL]]-1
  • CMA – zaneguj logicznie zawartość akumulatora A
  • DAA – wykonaj korekcję dziesiętną
  • RLC – przesuń zawartość akumulatora A w lewo
    c80802_02.png
  • RRC – przesuń zawartość akumulatora A w prawo
    c80802_03.png
  • RAL – przesuń zawartość akumulatora A w lewo
    c80802_04.png
  • RAR – przesuń zawartość akumulatora A w prawo
    c80802_05.png

V. Grupa instrukcja arytmetycznych 16-bitowych

  • DAD B – dodaj do zawartości pary rejestrów HL zawartość pary rejestrów BC
    [HL] ← [HL]+[BC]
  • DAD D – dodaj do zawartości pary rejestrów HL zawartość pary rejestrów DE
    [HL] ← [HL]+[DE]
  • DAD H – dodaj do zawartości pary rejestrów HL zawartość pary rejestrów HL
    [HL] ← [HL]+[HL]
  • DAD SP – dodaj do zawartości pary rejestrów HL zawartość rejestru SP
    [HL] ← [HL]+[SP]
  • INX B – zwiększ zawartość pary rejestrów BC o 1
    [BC] ← [BC]+1
  • INX D – zwiększ zawartość pary rejestrów DE o 1
    [DE] ← [DE]+1
  • INX H – zwiększ zawartość pary rejestrów HL o 1
    [HL] ← [HL]+1
  • INX SP – zwiększ zawartość rejestru SP o 1
    [SP] ← [SP]+1
  • DCX B – zmniejsz zawartość pary rejestrów BC o 1
    [BC] ← [BC]-1
  • DCX D – zmniejsz zawartość pary rejestrów DE o 1
    [DE] ← [DE]-1
  • DCX H – zmniejsz zawartość pary rejestrów HL o 1
    [HL] ← [HL]-1
  • DCX SP – zmniejsz zawartość rejestru SP o 1
    [SP] ← [SP]-1

VI. Grupa instrukcji skoków, wywołania i powrotu z podprogramów

  • JMP adr16 – wykonaj bezwarunkowy skok do miejsca określonego przez adr16
    [PC] ← adr16
  • PCHL – wykonaj skok bezwarunkowy do miejsca określonego przez zawartość pary rejestrów HL
    [PC] ← [HL]
  • JC adr16 – wykonaj warunkowy skok (wskaźnik C=1) do miejsca określonego przez adr16
    [PC] ← adr16
  • JNC adr16 – wykonaj warunkowy skok (wskaźnik C=0) do miejsca określonego przez adr16
    [PC] ← adr16
  • JZ adr16 – wykonaj warunkowy skok (wskaźnik Z=1) do miejsca określonego przez adr16
    [PC] ← adr16
  • JNZ adr16 – wykonaj warunkowy skok (wskaźnik Z=0) do miejsca określonego przez adr16
    [PC] ← adr16
  • JP adr16 – wykonaj warunkowy skok (wskaźnik S=0) do miejsca określonego przez adr16
    [PC] ← adr16
  • JM adr16 – wykonaj warunkowy skok (wskaźnik S=1) do miejsca określonego przez adr16
    [PC] ← adr16
  • JPE adr16 – wykonaj warunkowy skok (wskaźnik P=1) do miejsca określonego przez adr16
    [PC] ← adr16
  • JPO adr16 – wykonaj warunkowy skok (wskaźnik P=0) do miejsca określonego przez adr16
    [PC] ← adr16
  • CALL adr16 – wykonaj bezwarunkowy skok ze śladem do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CC adr16 – wykonaj warunkowy skok ze śladem (wskaźnik C=1) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CNC adr16 – wykonaj warunkowy skok ze śladem (wskaźnik C=0) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CZ adr16 – wykonaj warunkowy skok ze śladem (wskaźnik Z=1) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CNZ adr16 – wykonaj warunkowy skok ze śladem (wskaźnik Z=0) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CP adr16 – wykonaj warunkowy skok ze śladem (wskaźnik S=0) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CM adr16 – wykonaj warunkowy skok ze śladem (wskaźnik S=1) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CPE adr16 – wykonaj warunkowy skok ze śladem (wskaźnik P=1) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • CPO adr16 – wykonaj warunkowy skok ze śladem (wskaźnik P=0) do miejsca określonego przez adr16 (wywołaj podprogram)
    [[SP]] ← [PC]
    [SP] ← [SP]-2
    [PC] ← adr16
  • RET – wykonaj bezwarunkowy skok według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RC – wykonaj warunkowy skok (wskaźnik C=1) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RNC – wykonaj warunkowy skok (wskaźnik C=0) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RZ – wykonaj warunkowy skok (wskaźnik Z=1) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RNZ – wykonaj warunkowy skok (wskaźnik Z=0) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RM – wykonaj warunkowy skok (wskaźnik S=1) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RP – wykonaj warunkowy skok (wskaźnik S=0) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RPE – wykonaj warunkowy skok (wskaźnik P=1) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2
  • RPO – wykonaj warunkowy skok (wskaźnik P=0) według śladu (wróć z podprogramu)
    [PC] ← [[SP]]
    [SP] ← [SP]+2

VII. Grupa instrukcji sterujących jednostką centralną

  • EI – odblokuj przyjmowanie przerwań
  • DI – zablokuj przyjmowanie przerwań
  • RST q – wykonaj restart od miejsca wskazanego przez q (q=0, 1, 2, 3, 4, 5, 6 lub 7)
  • STC – ustaw wskaźnik C na 1
  • CMC – odwróć wskaźnik C na przeciwny
  • NOP – instrukcja pusta
  • HLT – zatrzymaj wykonanie programu

Rozszerzenia w mikroprocesorze I8085.

  • RIM – Wpisuje do akumulatora następujące informacje
    c80802_06.png
  • SIM – Instrukcja do manipulacji stanem procesora w oparcie o stan akumulatora, jak poniżej
    c80802_07.png

Wsparcie tylko dla członków naszej społeczności :) → dokument z tabelkami:
I8080 lista instrukcji.pdf
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 00:47

Kompilacja warunkowa

Podobnie jak w języku C, można z kodzie umieścić zaklęcia do kompilacji warunkowej. Są to:
  • .if <warunek>

    .endif
  • if <warunek>

    .else

    .endif
  • .ifdef <symbol>

    .endif
  • ifdef <symbol>

    .else

    .endif
  • .ifndef <symbol>

    .endif
  • .ifndef <symbol>

    .else

    .endif
Do tego dochodzi zaklęcie do definiowania symboli
.def <symbol> = <wartość logiczna>
W wyrażeniach <warunek> mogą wystąpić stałe true oraz false, zdefiniowane wcześniej (przez .def) symbole. W wyrażeniu mogą wystąpić operatory logiczne and, or, xor oraz not.

Przykład użycia (raport z kompilacji):

Kod: Zaznacz cały

Improved compiler for INTEL 8080/8085 processor, version 1.10, licence: CC BY 3.0

  L.NO MEMO    CODE         SRC

Open file: D:\lazarus_project\I8080\test5.asm
    1.                 ;
    2.                 ; Program testowy dla kompilatora
    3.                 ;
    4.                  .if true
    5.                 ;   wariant 1
    6. 0001             .def def1 = true
    7. 0001             .def def2 = true
    8. 0000             .def def3 = false
    9.                 ;
   10.                  .endif
   11.                  .if false
   12.                  ;   wariant 2
   13.                  .
   14.                  .  Tu mozna wpisac wszystko - nie bedzie kompilowane
   15.                  .
   16.                  .def def1 = true
   17.                  .def def2 = true
   18.                  .def def3 = true
   19.                  ;
   20.                  .endif
   21.                  .ifndef hardcore
   22. 0001             .def def4 = true
   23. 0001             .def hardcore = true
   24.                  .else
   25.                  .def def4 = false
   26.                  .endif
   27.                       .org   0h
   28. 0000 00         start      nop         ;
   29. 0001 3C               inr   a      ;
   30. 0002 04               inr   b      ;
   31. 0003 0C               inr   c      ;
   32. 0004 14               inr   d      ;
   33.                  .if def1 xor def2 xor def3 xor def4
   34.                        inx   h      ;
   35.                        inx   b      ;
   36.                        inx   d      ;
   37.                        inx   sp      ;
   38.                  .if true
   39.                        add   b      ;
   40.                        add   c      ;
   41.                        add   d      ;
   42.                        add   e      ;
   43.                  .if false
   44.                        add   m      ;
   45.                  .endif
   46.                        ana   b      ;
   47.                        ana   c      ;
   48.                        ani   0abh      ;
   49.                        ana   m      ;
   50.                  .else
   51.                        rra         ;
   52.                        rrl         ;
   53.                  .endif
   54.                        ral         ;
   55.                        rar         ;
   56.                  .else
   57. 0005 00               nop         ;
   58. 0006 00               nop         ;
   59. 0007 00               nop         ;
   60. 0008 00               nop         ;
   61. 0009 00               nop         ;
   62. 000A 00               nop         ;
   63. 000B 00               nop         ;
   64. 000C 00               nop         ;
   65. 000D 00               nop         ;
   66. 000E 00               nop         ;
   67. 000F 00               nop         ;
   68. 0010 00               nop         ;
   69.                  .endif
   70. 0011 29               dad   h      ;
   71. 0012 19               dad   d      ;
   72. 0013 09               dad   b      ;
   73. 0014 39               dad   sp      ;
   74. 0015 C31500     my      jmp   my      ;
   75.                        .end
Close file: D:\lazarus_project\I8080\test5.asm

Compilation :successful


Map information about constants and labels:
my                               LABEL:0015 hex
start                            LABEL:0000 hex


Code stored in file: D:\lazarus_project\I8080\test5.hex

Po kolumnie MEMO można zorientować się, jakie fragmenty programu źródłowego wchodzą do kompilacji, które są pominięte.
c80803_01.png


Użyte przykłady:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 01:23

Wybór procesora

W programie źródłowym można zawrzeć informację dotyczącą modelu mikroprocesora, na jaki jest generowany kod programu. Lista instrukcji procesora I8085 jest o dwie instrukcje bogatsza w stosunku do listy instrukcji procesora I8080. Są to instrukcji RIN oraz SIM. Zaklęcie .I8080 informuje kompilator, że używany jest procesor 8080. Analogicznie .I8085 dołącza do dopuszczalnych instrukcji dwie dodatkowe. Zastępczo jest ustalony wariant .I8080.
Zbiór wszystkich możliwych instrukcji jest następujący:

Kod: Zaznacz cały

;
;  ***************************************************
;  *                                                 *
;  *                                                 *
;  *    zbior instrukcji mikroprocesora 8085         *
;  *                                                 *
;  *                                                 *
;  ***************************************************
;
        .i8085
        .org 0
Data16  .equ 1234h
Data8   .equ 56h
Hello   .defb   'Hello world'
        HLT                              ; 76
        ACI Data8                        ; CE56
        ADC A                            ; 8F
        ADC B                            ; 88
        ADC C                            ; 89
        ADC D                            ; 8A
        ADC E                            ; 8B
        ADC H                            ; 8C
        ADC L                            ; 8D
        ADC M                            ; 8E
        ADD A                            ; 87
        ADD B                            ; 80
        ADD C                            ; 81
        ADD D                            ; 82
        ADD E                            ; 83
        ADD H                            ; 84
        ADD L                            ; 85
        ADD M                            ; 86
        ADI Data8                        ; C656
        ANA A                            ; A7
        ANA B                            ; A0
        ANA C                            ; A1
        ANA D                            ; A2
        ANA E                            ; A3
        ANA H                            ; A4
        ANA L                            ; A5
        ANA M                            ; A6
        ANI Data8                        ; E656
        CALL Data16                      ; CD3412
        CC Data16                        ; DC3412
        CM Data16                        ; FC3412
        CMA                              ; 2F
        CMC                              ; 3F
        CMP A                            ; BF
        CMP B                            ; B8
        CMP C                            ; B9
        CMP D                            ; BA
        CMP E                            ; BB
        CMP H                            ; BC
        CMP L                            ; BD
        CMP M                            ; BE
        CNC Data16                       ; D43412
        CNZ Data16                       ; C43412
        CP Data16                        ; F43412
        CPE Data16                       ; EC3412
        CPI Data8                        ; FE56
        CPO Data16                       ; E43412
        CZ Data16                        ; CC3412
        DAA                              ; 27
        DAD B                            ; 09
        DAD D                            ; 19
        DAD H                            ; 29
        DAD SP                           ; 39
        DCR A                            ; 3D
        DCR B                            ; 05
        DCR C                            ; 0D
        DCR D                            ; 15
        DCR E                            ; 1D
        DCR H                            ; 25
        DCR L                            ; 2D
        DCR M                            ; 35
        DCX B                            ; 0B
        DCX D                            ; 1B
        DCX H                            ; 2B
        DCX SP                           ; 3B
        DI                               ; F3
        EI                               ; FB
        HLT                              ; 76
        IN Data8                         ; DB56
        OUT Data8                        ; D356
        INR A                            ; 3C
        INR B                            ; 04
        INR C                            ; 0C
        INR D                            ; 14
        INR E                            ; 1C
        INR H                            ; 24
        INR L                            ; 2C
        INR M                            ; 34
        INX B                            ; 03
        INX D                            ; 13
        INX H                            ; 23
        INX SP                           ; 33
        JC Data16                        ; DA3412
        JM Data16                        ; FA3412
        JMP Data16                       ; C33412
        JNC Data16                       ; D23412
        JNZ Data16                       ; C23412
        JP Data16                        ; F23412
        JPE Data16                       ; EA3412
        JPO Data16                       ; E23412
        JZ Data16                        ; CA3412
        LDA Data16                       ; 3A3412
        LDAX B                           ; 0A
        LDAX D                           ; 1A
        LHLD Data16                      ; 2A3412
        LXI B,Data16                     ; 013412
        LXI D,Data16                     ; 113412
        LXI H,Data16                     ; 213412
        LXI SP,Data16                    ; 313412
        MOV A,A                          ; 7F
        MOV A,B                          ; 78
        MOV A,C                          ; 79
        MOV A,D                          ; 7A
        MOV A,E                          ; 7B
        MOV A,H                          ; 7C
        MOV A,L                          ; 7D
        MOV A,M                          ; 7E
        MOV B,A                          ; 47
        MOV B,B                          ; 40
        MOV B,C                          ; 41
        MOV B,D                          ; 42
        MOV B,E                          ; 43
        MOV B,H                          ; 44
        MOV B,L                          ; 45
        MOV B,M                          ; 46
        MOV C,A                          ; 4F
        MOV C,B                          ; 48
        MOV C,C                          ; 49
        MOV C,D                          ; 4A
        MOV C,E                          ; 4B
        MOV C,H                          ; 4C
        MOV C,L                          ; 4D
        MOV C,M                          ; 4E
        MOV D,A                          ; 57
        MOV D,B                          ; 50
        MOV D,C                          ; 51
        MOV D,D                          ; 52
        MOV D,E                          ; 53
        MOV D,H                          ; 54
        MOV D,L                          ; 55
        MOV D,M                          ; 56
        MOV E,A                          ; 5F
        MOV E,B                          ; 58
        MOV E,C                          ; 59
        MOV E,D                          ; 5A
        MOV E,E                          ; 5B
        MOV E,H                          ; 5C
        MOV E,L                          ; 5D
        MOV E,M                          ; 5E
        MOV H,A                          ; 67
        MOV H,B                          ; 60
        MOV H,C                          ; 61
        MOV H,D                          ; 62
        MOV H,E                          ; 63
        MOV H,H                          ; 64
        MOV H,L                          ; 65
        MOV H,M                          ; 66
        MOV L,A                          ; 6F
        MOV L,B                          ; 68
        MOV L,C                          ; 69
        MOV L,D                          ; 6A
        MOV L,E                          ; 6B
        MOV L,H                          ; 6C
        MOV L,L                          ; 6D
        MOV L,M                          ; 6E
        MOV M,A                          ; 77
        MOV M,B                          ; 70
        MOV M,C                          ; 71
        MOV M,D                          ; 72
        MOV M,E                          ; 73
        MOV M,H                          ; 74
        MOV M,L                          ; 75
        MVI A,Data8                      ; 3E56
        MVI B,Data8                      ; 0656
        MVI C,Data8                      ; 0E56
        MVI D,Data8                      ; 1656
        MVI E,Data8                      ; 1E56
        MVI H,Data8                      ; 2656
        MVI L,Data8                      ; 2E56
        MVI M,Data8                      ; 3656
        NOP                              ; 00
        ORA A                            ; B7
        ORA B                            ; B0
        ORA C                            ; B1
        ORA D                            ; B2
        ORA E                            ; B3
        ORA H                            ; B4
        ORA L                            ; B5
        ORA M                            ; B6
        ORI Data8                        ; F656
        PCHL                             ; E9
        POP B                            ; C1
        POP D                            ; D1
        POP H                            ; E1
        POP PSW                          ; F1
        PUSH B                           ; C5
        PUSH D                           ; D5
        PUSH H                           ; E5
        PUSH PSW                         ; F5
        RAL                              ; 17
        RAR                              ; 1F
        RC                               ; D8
        RET                              ; C9
        RLC                              ; 07
        RM                               ; F8
        RNC                              ; D0
        RNZ                              ; C0
        RP                               ; F0
        RPE                              ; E8
        RPO                              ; E0
        RRC                              ; 0F
        RST 0                            ; C7
        RST 1                            ; CF
        RST 2                            ; D7
        RST 3                            ; DF
        RST 4                            ; E7
        RST 5                            ; EF
        RST 6                            ; F7
        RST 7                            ; FF
        RZ                               ; C8
        SBB A                            ; 9F
        SBB B                            ; 98
        SBB C                            ; 99
        SBB D                            ; 9A
        SBB E                            ; 9B
        SBB H                            ; 9C
        SBB L                            ; 9D
        SBB M                            ; 9E
        SBI Data8                        ; DE56
        SHLD Data16                      ; 223412
        SPHL                             ; F9
        STA Data16                       ; 323412
        STAX B                           ; 02
        STAX D                           ; 12
        STC                              ; 37
        SUB A                            ; 97
        SUB B                            ; 90
        SUB C                            ; 91
        SUB D                            ; 92
        SUB E                            ; 93
        SUB H                            ; 94
        SUB L                            ; 95
        SUB M                            ; 96
        SUI Data8                        ; D656
        XCHG                             ; EB
        XRA A                            ; AF
        XRA B                            ; A8
        XRA C                            ; A9
        XRA D                            ; AA
        XRA E                            ; AB
        XRA H                            ; AC
        XRA L                            ; AD
        XRA M                            ; AE
        XRI Data8                        ; EE56
        XTHL                             ; E3
        RIM                              ; 20
        SIM                              ; 30
.end


Użyty przykład:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 01:40

Stałe w programie

W programie można wprowadzić stałą nadając jej określoną wartość. Postać zapisu jest następująca:

<stała> .equ <wyrażenie>

Nie musi to być stała jako taka. W <wyrażenie> może wystąpić dowolne wyrażenie z operatorami arytmetycznymi, logicznymi oraz przesunięcia. Wszelkie chwyty są dozwolone a jedynym warunkiem jest to, by wyrażenie przed końcem zbioru było policzalne (elementy występujące w wyrażeniu mogą zostać określone później). W szczególnym przypadku są to etykiety w programie, które mają wartość wynikającą z jej adresu w przestrzeni pamięci. Jako stałe mogą wystąpić liczby binarne (z literką B na końcu), szesnastkowe (z literką H) na końcu, dziesiętne (bez oznaczenia literkowego na końcu), kody znaków jedno (8-bitów) lub dwuznakowych (16-bitów).
W wyrażeniach mogą wystąpić następujące operatory:
  • + – operator dodawania arytmetycznego,
  • * – operator mnożenia arytmetycznego,
  • - – operator odejmowania arytmetycznego lub negacji arytmetycznej
  • / operator dzielenia całkowitoliczbowego,
  • mod ( <dzielna> , <dzielnik> ) – funkcja dająca resztę z dzielenia <dzielna> przez <dzielnik>,
  • shr – operator przesunięcia w prawo o określoną liczbę bitów w notacji <wartość> shr <liczba bitów>,
  • > – tożsame z shr,
  • shl – operator przesunięcia w lewo o określoną liczbę bitów w notacji <wartość> shl <liczba bitów>,
  • < – tożsame z shl,
  • or – operator sumy logicznej wykonanej na bitach,
  • & – operator iloczynu logicznego wykonanego na bitach,
  • xor – operator logiczny sumy exclusive or wykonanej na bitach,
  • ^ – tożsame z xor,
  • not – operator negacji logicznej wykonanej na bitach,
  • ~ – tożsame z not,
  • lo ( <wyrażenie> ) – funkcja dająca młodsze 8 bitów z wyrażenia 16-bitowego,
  • hi ( <wyrażenie> ) – funkcja dająca starsze 8 bitów z wyrażenia 16-bitowego,
  • sizeof ( <identyfikator typu> ) – funkcja dająca wielkość typu wyrażoną w bajtach.

Przykład użycia (abstrakcyjny):

Kod: Zaznacz cały

;
; Compiler test program
;
   .org   100h
c1   .equ   "aA"               ; =6141
c2   .equ   c1 > 4            ; =0614
c2a   .equ   c1 shr 4            ; =0614
c3   .equ   c1 < 8            ; =4100
c3a   .equ   c1 shl 8            ; =4100
c4   .equ   c1 shr 0            ; =6141
c5   .equ   5Ah               ; =005A
c6   .equ   10101010b            ; =00AA
c7   .equ   10 + c6            ; =00B4
c8   .equ   'A'               ; =0041
c9   .equ   'B'               ; =0042
c10   .equ   c8 + c9            ; =0083
c11   .equ   c7 * 'A'            ; =2DB4
c12   .equ   c5 / ' '            ; =0002
c12m   .equ   mod ( c5 , ' ' )         ; =001A
c13   .equ   c5 * c8            ; =16DA
c14   .equ   'A' * 'a'            ; =18A1
c15   .equ   'a' - 'A'            ; =0020
c16   .equ   c5 * ( c7 + c10 ) + 1000h   ; =7D56
c17   .equ   lo ( c16 )            ; =0056
c18   .equ   hi ( c16 )            ; =007D
c19   .equ   c17 & c18            ; =0054
c20   .equ   c5 or c2              ; =065E
c21   .equ   c10  ^ 0ffh            ; =007C
c22   .equ   lo ( ~ c1 )            ; =00BE
c23   .equ   ( not c1 )            ; =9EBE
c24   .equ   label1 - label3         ;
c25   .equ   c26 + c24            ;
c26   .equ   (label1+label2)/c5+c7+c8   ; =00FA
label1   .defb   '*****'
c27   .equ   (label1 + c25 ) / c5 + c7   ;
label2   .defm   '#####'
c28   .equ   (label1+label2)/c5+c6*c27   ;
   .end

Program jest niekompilowalny by pokazać ideę działania kompilatora. Będzie on do końca kombinował, by policzyć wartości wyrażeń. Ze względu na brak etykiety label3, nie da się obliczyć wartości wyrażenia identyfikowanego przez c24. Brak c24 powoduje, że wyrażenie na c25 jest niepoliczalne. To z kolei uniemożliwia obliczenia wartości wyrażeń oznaczonych jako c27 i w dalszej kolejności c28.
Wszystkie stałe mogą wystąpić w operandach instrukcji, jako wartości w stałych obszarach danych oraz w deklaracji zmiennych. W zależności od kontekstu użycia brana jest wartość jako 8-bitowa lub 16-bitowa. W przypadku 8-bitowym prowadzona jest kontrola wartości (czy operand mieści się w 8 bitach). Operand 16-bitowy mieści się zawsze (obliczenia wartości są realizowane w arytmetyce 16-bitowej).
Inny przykład (abstrakcyjny):

Kod: Zaznacz cały

;
; Compiler test program
;
   .org   0h
c1:   .equ   'aA'
c2:   .equ   c1 > 4
c3:   .equ   c1 < 8
c4:   .equ   c1 < 0
c5   .equ   5Ah
c6   .equ   10101010b
c7   .equ   10 + c6
c8   .equ   'A'
c9   .equ   'B'
code1   .defw   "string example 1",'string example 2!'
code2   .defw   1,2,C1,C2,C5 | C6,c7*(c8+c9)
code3   .defw   label1,label2+c5,label1+label3,start
   .defw   label2 - label1,code1
   .defb   1,2,lo(C1),C2>4,label2-label1
   .defw   'X'+c8
   .defw   -c8,c8
   .defw   ~c5,c5
   .defw   (c1+c2)*c3
   .defw   c7*(c8+c9) + c1
   .defw   ( c1 > 8 ) + 1
   .defb   hi ( c7 * ( c8 + c9) + c1 ) , lo ( ( c1 > 8 ) + 1 )
   .defb   mod ( hi ( c7 * ( c8 + c9 ) + c1 ) , lo ( ( c1 > 8 ) + 1 ) )
label1   .defb   '****'
text   .defm   'I8080 - przyklad programu','Inny przyklad'
label2   .defb   '####'
label3   nop
start:
   halt
   .end

Wyrażenia mogą występować również jako operandy w instrukcjach:

Kod: Zaznacz cały

;
; Compiler test program
;
   .org   0h
   JMP   Start
;
; **************************************************************************
; *                                                                        *
; *                                                                        *
; *    zbior instrukcji kompilatora assemblera mikroprocesora I8080        *
; *                                                                        *
; *                                                                        *
; **************************************************************************
;
vv1   .equ   12
vv2   .equ   'aa'
vv3   .equ   23h
vv4   .equ   3
vv5   .equ   1212
bitno   .equ   3
const   .equ   111
dis   .equ   10h
;
Text1   .defm   '***** zestaw analizowanych instrukcji *****'
Text2   .defm   '*****  mikroprocesora 8080 ( INTEL )  *****'
Start
   LXI   H , Text1 + const
   LXI   H , var6 + const
   LXI   H , ( Text1 + const )
   LXI   H , ( var6 + const )
   LXI   H , ( vv1 + vv2 ) * ( vv3 + vv4 )
CallLabel
   NOP
lab1   LXI   SP , Text1
lab2   LXI   D , Dest
lab3   LXI   B , Text2 - Text1
lab4   LXI   SP , lab4
   MVI   A , lo ( lab1 )
   MVI   A , lab1 & 0FFh
   MVI   B , hi ( lab1 )
   MVI   B , lab1 > 8
   MVI   C , lo ( label1 )
   MVI   C , label1 & 0FFH
   MVI   D , lo ( label1 )
   MVI   E , hi ( label1 )
   MVI   H , label1 > 8
   MVI   L , '?'
   MVI   B , vv1
   MVI   C , vv2
   MVI   D , vv3
   MVI   E , vv1 + vv3
   MVI   H , vv1 & vv3
   MVI   L , vv4 < 3
   LDA   1212
   LDA   ( lab1 + dis * const )
   LDA   ( label1 - const - 1 )
   ANI   lo ( 1 < bitno )
   JNZ   BitNotSet
fict2   .equ   vv1 * vv4 + 7
fict3   .equ   - vv1 * vv4 + 7
   STA   1234
   STA   var1
   STA   var2 + var3
   STA   ( var4 + 1 ) * 3
   STA   ( var5 - 1 ) * dis
   STA   var6 + dis
   MVI   M , lo ( text1 )
   MVI   M , lo ( var1 )
   ADI   lo ( label1 + 5 )
   SUI   hi ( text1 > 4 )
   ANI   lo ( ( label3 < 4 ) + 7 )
   ORI   vv4 * 'A'
;
fict1   .equ   ( vv1 + vv2 ) * ( vv3 + vv4 )
;
   XRI   lo ( ( vv1 + vv2 ) * ( vv3 + vv4 ) )
   CPI   hi ( ( vv1 + vv2 ) * ( vv3 + vv4 ) )
   RST   1+2+3
next   NOP
EE   NOP
   JP   EE
   JM   EE
   JC   EE
   JZ   EE
   JPE   EE
   JMP   EEE
   NOP
BitNotSet
EEE   HLT
prt   .equ   16h
label1   IN   lo ( prt + dis * 'A' + const )
label2   IN   prt
label3   IN   123
label4   IN   lo ( text1 )
JumpLabel
   OUT   ( lo ( prt + dis * 'A' + const ) )
   .org   400H
Dest   .defs   128
var1   .byte
var2   .byte
var3   .byte
var4   .byte
var5   .byte
var6   .byte
   .end


Użyte przykłady:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 13:36

Zmienne

Kompilator rozpoznaje standardowe typy zmiennych, tj. zmienne o rozmiarze jednego bajta, dwóch bajtów oraz czterech bajtów. Deklaracja zmiennych ma następującą syntaktykę:

<nazwa zmiennej> .<typ zmiennej> <opcjonalnie wielkość>

jako typ zmiennej może wystąpić:
  • .byte – typ zmiennej zajmującej jeden bajt,
  • .word – typ zmiennej zajmującej dwa baty,
  • .long – typ zmiennej zajmującej cztery bajty.
Kompiler toleruje również archaiczne zaklęcie
<nazwa zmiennej> .defs <wielkość obszaru>
które rezerwuje dla zmiennej obszar pamięci o podanej wielkości. Zastąpienie zaklęcia .defs przez .byte daje tożsamy efekt.
Można zdefiniować własny typ zmiennej jako strukturę (analogia do typu record w języku PASCAL lub struct w języku C). Postać zapisu jest następująca:

Kod: Zaznacz cały

<identyfikator typu> .struct
                     <opis pola>
                     <opis pola>
                     <opis pola>
                     <opis pola>
                     .endstruct

Przykład:

Kod: Zaznacz cały

f1size        .equ      4
f2size        .equ      8
factor        .equ      4
Type1         .struct
      field1  .byte     f1size * factor
      field2  .byte     f2size * factor
      field3  .word     f2size
      field4  .long
              .endstruct

Odpowiada to utworzeniu obszaru na zmienną o wielkości wynikającej z sumy wszystkich pól. Jednocześnie tworzy stałe określające położenia pól względem początku.
c80804_01.png

Po zdefiniowaniu typu można powołać zmienną nowego typu oraz w operandach instrukcji używać wprowadzonych symboli. Przykładowo:

Kod: Zaznacz cały

f1size      .equ   4
f2size      .equ   8
factor      .equ   4
Type1       .struct
              field1     .byte  f1size * factor
              field2     .byte  f2size * factor
              field3     .word  f2size
              field4     .long
      .endstruct

( . . . )

     mvi  '*'
     sta  variable + Type1 . Field3

( . . . )

variable   .Type1

c80804_02.png

Z typami związana jest funkcja, którą można używać we wszystkich wyrażeniach (przy definiowaniu stałych, tworzeniu obszarów stałych i w operandach instrukcji). Jest to:
  • sizeof ( <typ> ) – funkcja zwraca wielkość całego typu wyrażoną w bajtach,
  • sizeof ( <typ>.<pole> ) – funkcja zwraca wielkość określonego pola w strukturze określonej przez podaną nazwę typu.
Przykład

Kod: Zaznacz cały

Improved compiler for INTEL 8080/8085 processor, version 2.0, licence: CC BY 3.0

  L.NO MEMO    CODE         SRC

Open file: D:\microgeek\asm8080\test7.asm
    1.                 ;
    2.                 ; Compiler test program
    3.                 ;
    4.                       .org   0h
    5. 0004            f1size        .equ      4
    6. 0008            f2size        .equ      8
    7. 0004            factor        .equ      4
    8. 0044            Type1      .struct
    9. 0010               field1   .byte   f1size * factor
   10. 0020               field2   .byte   f2size * factor
   11. 0010               field3   .word   f2size
   12. 0004               field4   .long
   13.                       .endstruct
   14. 0004            Type2      .struct
   15. 0001               field1   .byte
   16. 0001               field2   .byte
   17. 0002               field3   .word
   18.                       .endstruct
   19.                 ;
   20. 0007            Type3      .struct
   21. 0004               field1   .long
   22. 0002               field2   .word
   23. 0001               field3   .byte
   24.                       .endstruct
   25.                 ;
   26. 0001            expr1      .equ   sizeof ( byte )
   27. 0002            expr2      .equ   sizeof ( word )
   28. 0004            expr3      .equ   sizeof ( long )
   29. 0044            expr4      .equ   sizeof ( Type1 )
   30. 0010            expr41      .equ   sizeof ( Type1 . FIELD1 )
   31. 0020            expr42      .equ   sizeof ( Type1 . FIELD2 )
   32. 0010            expr43      .equ   sizeof ( Type1 . FIELD3 )
   33. 0004            expr44      .equ   sizeof ( Type1 . FIELD4 )
   34. 0004            expr5      .equ   sizeof ( Type2 )
   35. 0001            expr51      .equ   sizeof ( Type2 . field1 )
   36. 0001            expr52      .equ   sizeof ( Type2 . field2 )
   37. 0002            expr53      .equ   sizeof ( Type2 . field3 )
   38. 0007            expr6      .equ   sizeof ( Type3 )
   39. 0004            expr61      .equ   sizeof ( Type3 . field1 )
   40. 0002            expr62      .equ   sizeof ( Type3 . field2 )
   41. 0001            expr63      .equ   sizeof ( Type3 . field3 )
   42. 0047            expr7      .equ   sizeof ( byte ) + sizeof ( word ) + sizeof ( Type1 )
   43. 000C            expr8      .equ   ( sizeof ( byte ) + sizeof ( word ) ) * sizeof ( Type2 )
   44.                 ;
   45.                 ;
   46.                 ;
   47. 0000 00         start      nop
   48.                       mvi   '*'
   49. 0001 3200C0           sta   variable1
   50. 0004 3253C0           sta   variable5 + Type3 . field3
   51. 0007 2149C0           lxi   h , variable4
   52. 000A 010100           lxi     b , Type2 . field2
   53. 000D 09               dad   b
   54. 000E 77               mov   m , a
   55. 000F 3C               inr   a
   56. 0010 324AC0           sta     variable4 + Type2 . field2
   57. 0013 3A05C0           lda   Variable3 + Type1 . field1
   58. 0016 3200C0           sta   variable1
   59. 0019 C31900     halt      jmp   halt
   60.                       .org   0c000h
   61. C000            variable1   .byte   1
   62. C001            variable2   .word   2
   63. C005            variable3   .byte   sizeof ( Type1 )
   64. C049            variable4   .byte   sizeof ( Type2 )
   65. C04D            variable5   .byte   sizeof ( Type3 )
   66. C054            variable6   .Type1
   67. C098            variable7   .Type2   4
   68. C0A8            variable8   .Type3   8
   69. C0E0            variable9   .long
   70.                        .end
Close file: D:\microgeek\asm8080\test7.asm

Compilation :successful


Map information about constants and labels:
expr1                            CONST=0001 hex [0000000000000001 bin,1 dec]
expr2                            CONST=0002 hex [0000000000000010 bin,2 dec]
expr3                            CONST=0004 hex [0000000000000100 bin,4 dec]
expr4                            CONST=0044 hex [0000000001000100 bin,68 dec]
expr41                           CONST=0010 hex [0000000000010000 bin,16 dec]
expr42                           CONST=0020 hex [0000000000100000 bin,32 dec]
expr43                           CONST=0010 hex [0000000000010000 bin,16 dec]
expr44                           CONST=0004 hex [0000000000000100 bin,4 dec]
expr5                            CONST=0004 hex [0000000000000100 bin,4 dec]
expr51                           CONST=0001 hex [0000000000000001 bin,1 dec]
expr52                           CONST=0001 hex [0000000000000001 bin,1 dec]
expr53                           CONST=0002 hex [0000000000000010 bin,2 dec]
expr6                            CONST=0007 hex [0000000000000111 bin,7 dec]
expr61                           CONST=0004 hex [0000000000000100 bin,4 dec]
expr62                           CONST=0002 hex [0000000000000010 bin,2 dec]
expr63                           CONST=0001 hex [0000000000000001 bin,1 dec]
expr7                            CONST=0047 hex [0000000001000111 bin,71 dec]
expr8                            CONST=000C hex [0000000000001100 bin,12 dec]
f1size                           CONST=0004 hex [0000000000000100 bin,4 dec]
f2size                           CONST=0008 hex [0000000000001000 bin,8 dec]
factor                           CONST=0004 hex [0000000000000100 bin,4 dec]
halt                             LABEL:0019 hex
start                            LABEL:0000 hex
variable1                        LABEL:C000 hex
variable2                        LABEL:C001 hex
variable3                        LABEL:C005 hex
variable4                        LABEL:C049 hex
variable5                        LABEL:C04D hex
variable6                        LABEL:C054 hex type: Type1
variable7                        LABEL:C098 hex type: Type2
variable8                        LABEL:C0A8 hex type: Type3
variable9                        LABEL:C0E0 hex
Type1                            STRUCT, size=0044 hex [68 dec], orgin=0000 hex
        field1                           size=0010 hex [16 dec], offset=0 dec
        field2                           size=0020 hex [32 dec], offset=+16 dec
        field3                           size=0010 hex [16 dec], offset=+48 dec
        field4                           size=0004 hex [4 dec], offset=+64 dec
Type2                            STRUCT, size=0004 hex [4 dec], orgin=0000 hex
        field1                           size=0001 hex [1 dec], offset=0 dec
        field2                           size=0001 hex [1 dec], offset=+1 dec
        field3                           size=0002 hex [2 dec], offset=+2 dec
Type3                            STRUCT, size=0007 hex [7 dec], orgin=0000 hex
        field1                           size=0004 hex [4 dec], offset=0 dec
        field2                           size=0002 hex [2 dec], offset=+4 dec
        field3                           size=0001 hex [1 dec], offset=+6 dec


Code stored in file: D:\microgeek\asm8080\test7.hex

Poczynione działania mają swoje odbicie w raporcie z kompilacji:
c80804_03.png

Przy definiowaniu zmiennej można za identyfikatorem typu podać liczbę (ogólnie wyrażenie policzalne w chwili użycia). Brak takiej liczby jest tożsame z podaniem jej jako jeden. Taki zabieg oznacza zwielokrotnienie tworzonej zmiennej określoną liczbę razy i można to traktować jako array of <coś>.
W powyższym przykładzie wystąpiło:
variable3 .byte sizeof ( Type1 )
variable6 .Type1

i właściwie jest to tożsame: zajmuje w pamięci identyczny obszar natomiast kompilator nie kontroluje, czy używane zmienne i typy wzajemnie mają ze sobą coś wspólnego. To człowiek panuje nad wszystkim a kompilator ma jedynie pomóc.

Użyty przykład:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Ostatnio zmieniony niedziela 31 lip 2022, 15:19 przez gaweł, łącznie zmieniany 1 raz.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 14:08

Dopasowania

Czasami może się tak zdarzyć, że określona etykieta (etykieta w programie, zmienna) musi mieć parzysty adres. Pisząc program trudno jest zagwarantować, by taki wymóg został spełniony. By wesprzeć społeczność pisacieli, kompiler oferuje pewne wsparcie w postaci zaklęcia .align.
Postać zaklęcia jest następująca:

.align <liczba>

gdzie <liczba> to: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
Użycie tej formuły powoduje, że następny zapis będzie miał adres w pamięci dostosowany do oczekiwanych wymogów (podzielny przez podaną jako operand wartość).
Przykład użycia:

Kod: Zaznacz cały

Improved compiler for INTEL 8080/8085 processor, version 2.0, licence: CC BY 3.0

  L.NO MEMO    CODE         SRC

Open file: D:\microgeek\asm8080\test6.asm
    1.                 ;
    2.                 ; Compiler test program
    3.                 ;
    4.                       .org   0h
    5. 0000 00         start      nop
    6. 0001 CD4000           call   entry         ;
    7. 0004 C34200           jmp   stop            ;
    8.                       .align   64
    9. 0040 00         entry      nop            ;
   10. 0041 C9               ret               ;
   11. 0042 C34200     stop      jmp   stop            ;
   12.                 ;===============================================;
   13.                       .org   8000h            ;
   14. 8000            space      .defs   400h         ;
   15. 8400            screen   .defs   400h            ;
   16. 8800            var0      .byte            ;
   17.                       .align   2            ;
   18. 8802            var1      .byte            ;
   19.                       .align   2            ;
   20. 8804            var2      .byte            ;
   21.                       .align   2            ;
   22. 8806            var3      .byte            ;
   23.                       .align   2            ;
   24. 8808            var4      .byte            ;
   25.                       .align   2            ;
   26. 880A            var5      .word            ;
   27.                       .align   8            ;
   28. 8810            var6      .word            ;
   29.                       .align   256            ;
   30. 8900            var7      .byte   128         ;
   31. 8980            var8      .byte            ;
   32.                        .end
Close file: D:\microgeek\asm8080\test6.asm

Compilation :successful


Map information about constants and labels:
entry                            LABEL:0040 hex
screen                           LABEL:8400 hex
space                            LABEL:8000 hex
start                            LABEL:0000 hex
stop                             LABEL:0042 hex
var0                             LABEL:8800 hex
var1                             LABEL:8802 hex
var2                             LABEL:8804 hex
var3                             LABEL:8806 hex
var4                             LABEL:8808 hex
var5                             LABEL:880A hex
var6                             LABEL:8810 hex
var7                             LABEL:8900 hex
var8                             LABEL:8980 hex


Code stored in file: D:\microgeek\asm8080\test6.hex


Użyty przykład:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1182
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [ASM] Kompilator na I8080/I8085

Postautor: gaweł » niedziela 31 lip 2022, 15:09

Relokacja kodu

Czasami (a właściwie bardzo rzadko) zachodzi potrzeba relokacji kodu, czyli wykonania kodu programu, który jest <tutaj> (bo jego miejscem składowania jest <tutaj>) a powinien znajdować się w <innym miejscu>. Kompiler wspiera takie zagrywki i oferuje zaklęcie .radix. Ma ono następujący zapis:

.radix <lokacja w pamięci>

zapis w postaci

.radix $

oznacza powrót do normalności.
Zastosowanie tego zaklęcia powoduje, że raport kompilacji zawiera kolejną kolumnę LINK, która odpowiada miejscu uruchomienia kodu.
Przykład:

Kod: Zaznacz cały

Improved compiler for INTEL 8080/8085 processor, version 2.0, licence: CC BY 3.0

  L.NO MEMO LINK    CODE         SRC

Open file: D:\microgeek\asm8080\test4.asm
    1.                      ;
    2.                      ; Compiler test program
    3.                      ;
    4.                            .org   0h
    5. 0001                 AnyConst1   .equ   1
    6. 0002                 AnyConst2   .equ   2
    7. 0003                 AnyConst3   .equ   3
    8. 0004                 AnyConst4   .equ   4
    9. 0005                 AnyConst5   .equ   5
   10. 0006                 AnyConst6   .equ   6
   11. 0007                 AnyConst7   .equ   7
   12. 0000 0000 00         start      nop
   13.                      ;
   14. 0001 0001 310000           lxi   sp , 0         ;
   15. 0004 0004 211600           lxi   h , relsrc      ;
   16. 0007 0007 110080           lxi   d , space      ;
   17. 000A 000A 013500           lxi   b , rel_stop - rel_start;
   18. 000D 000D CD5500           call   copy         ;
   19. 0010 0010 CD2280           call   entry         ;
   20. 0013 0013 C34B00           jmp   continue      ;
   21.                      ;------------------------------------------------
   22. 0016 0016            relsrc
   23.                            .radix   8000h
   24. 0016 8000            rel_start
   25. 0016 8000 6D657373   message      .defm   'message to screen'
       001A      61676520
       001E      746F2073
       0022      63726565
       0026      6E
   26. 0027 8011 00         endmess      .defb   0
   27. 0028 8012 00001600   table      .defw   start , relsrc , rel_start , rel_stop
       002C      00803580
   28. 0030 801A 00801180         .defw   message , endmess , entry
       0034      2280
   29. 0036 8020 3380             .defw   label
   30. 0038 8022 00         entry      nop            ;
   31. 0039 8023 210080           lxi   h , message      ;
   32. 003C 8026 110084           lxi   d , screen      ;
   33. 003F 8029 011100           lxi   b , endmess - message   ;
   34. 0042 802C CD5500           call   copy
   35. 0045 802F CD3380           call   label         ;
   36. 0048 8032 C9               ret            ;
   37. 0049 8033 00         label      nop            ;
   38. 004A 8034 C9               ret            ;
   39. 004B 8035            rel_stop               ;
   40.                            .radix   $         ;
   41. 004B 004B 00         continue   nop            ;
   42. 004C 004C CD5300           call   cont1         ;
   43. 004F 004F 216000           lxi   h , stop      ;
   44. 0052 0052 E9               pchl            ;
   45. 0053 0053 00         cont1      nop            ;
   46. 0054 0054 C9               ret            ;
   47. 0055 0055 7E         copy      mov   a , m         ;
   48. 0056 0056 23               inx   h         ;
   49. 0057 0057 12               stax   d         ;
   50. 0058 0058 13               inx   d         ;
   51. 0059 0059 0B               dcx   b         ;
   52. 005A 005A 78               mov   a , b         ;
   53. 005B 005B B1               ora   c         ;
   54. 005C 005C C8               rz            ;
   55. 005D 005D C35500           jmp   copy         ;
   56.                            
   57. 0060 0060 76         stop      hlt            ;
   58. 0061 0061 C36000           jmp   stop         ;
   59.                      
   60.                      ;
   61.                            .org   8000h
   62. 8000 8000            space      .defs   400h
   63. 8400 8400            screen      .defs   400h
   64. 8800 8800            var0      .byte   10h
   65. 8810 8810            var1      .byte   10h
   66. 8820 8820            var2      .byte   10h
   67. 8830 8830            var3      .byte   10h
   68. 8840 8840            var4      .byte   10h
   69. 8850 8850            var5      .word   10h
   70. 8870 8870            var6      .word   10h
   71. 8890 8890            var7      .byte
   72.                             .end
Close file: D:\microgeek\asm8080\test4.asm

Compilation :successful


Map information about constants and labels:
AnyConst1                        CONST=0001 hex [0000000000000001 bin,1 dec]
AnyConst2                        CONST=0002 hex [0000000000000010 bin,2 dec]
AnyConst3                        CONST=0003 hex [0000000000000011 bin,3 dec]
AnyConst4                        CONST=0004 hex [0000000000000100 bin,4 dec]
AnyConst5                        CONST=0005 hex [0000000000000101 bin,5 dec]
AnyConst6                        CONST=0006 hex [0000000000000110 bin,6 dec]
AnyConst7                        CONST=0007 hex [0000000000000111 bin,7 dec]
cont1                            LABEL:0053 hex
continue                         LABEL:004B hex
copy                             LABEL:0055 hex
endmess                          LABEL:8011 hex
entry                            LABEL:8022 hex
label                            LABEL:8033 hex
message                          LABEL:8000 hex
relsrc                           LABEL:0016 hex
rel_start                        LABEL:8000 hex
rel_stop                         LABEL:8035 hex
screen                           LABEL:8400 hex
space                            LABEL:8000 hex
start                            LABEL:0000 hex
stop                             LABEL:0060 hex
table                            LABEL:8012 hex
var0                             LABEL:8800 hex
var1                             LABEL:8810 hex
var2                             LABEL:8820 hex
var3                             LABEL:8830 hex
var4                             LABEL:8840 hex
var5                             LABEL:8850 hex
var6                             LABEL:8870 hex
var7                             LABEL:8890 hex


Code stored in file: D:\microgeek\asm8080\test4.hex


Raport z kompilacji zawiera:
c80805_01.png

Mechanizm ten może okazać się przydatny przy bootowaniu systemu, gdzie kod programu musi w swoje miejsce załadować kod z jakiegoś nośnika. Skoro jest ładowany w swoje miejsce, to kod ładujący musi się przepisać w inne i z tamtego miejsca wykonać przewidziane operacje.

Użyte przykłady:
uzyte_przyklady.7z
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse


Wróć do „Retro”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości