Autor Wątek: Deasemblacja  (Przeczytany 12258 razy)

Frodo

  • *
  • Wiadomości: 18
Deasemblacja
« dnia: 2015.12.22, 16:16:15 »
Może nie uda się zrobić emulatora, ale chciałbym zrobić wyświetlanie mnemoników dla bajtów. Najlepsza chyba lista instrukcji to http://wikiti.brandonw.net/index.php?title=Z80_Instruction_Set
- jest to tabelka, którą można przenieść do pliku tekstowego czy Excela
- uogólniony opis rozkazów typy [adc a,R | 10001rrr]
- podany czas w taktach, choć czasem nie rozumiem zapisu 17/10 dla call
poza tym nie tylko dla deasemblacji:
- dokładny opis co się dzieje z flagami
- opis co instrukcja robi
Jak można zastosować to do deasemblacji, mając strumień bitów wypluwać mnemoniki i jak ewentualnie zakodować akcje, aby nie pisać dla każdego kodu funkcji?

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Deasemblacja
« Odpowiedź #1 dnia: 2015.12.22, 16:53:09 »
Też tego nie zrobisz.

Powiedz Frodo, co do tej pory zrobiłeś na Spectrum albo związanego ze Spectrum?

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Deasemblacja
« Odpowiedź #2 dnia: 2015.12.22, 18:01:21 »
A ja zachęcam do pisania takiego dissasemblera. Bardzo wiele można się przy tym nauczyć, jak chociażby co oznacza 7/10 oraz wszelkie te 'dziwne oznaczenia'.

zacząłbym od zaznajomienia się z architekturą procesora, a dokładniej z informacją o rejestrach, trybach adresowania, opcodach i jak je ugryźć. Link, który podałeś będzie pomocny. W razie czego - pytaj.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Deasemblacja
« Odpowiedź #3 dnia: 2015.12.23, 09:15:07 »
Co do najlepszości to ja tam bym się sprzeczał ;)

Na początek zajrzałbym do oficjalnej dokumentacji produktu. Nie ma w niej "nieudokumentowanych" rozkazów, ale cała reszta jest opisana bardzo dokładnie i szczegółowo. Dalsze informacje to Home of the Z80 CPU - tam znajdziesz mnóstwo informacji na wszystkie tematy związane z Z80 w tym również do opisów listy rozkazów uwzględniającej nieoficjalne rozkazy. "Rozpiskę" rozkazów znajdziesz też na naszym Wiki.

Jak już zdecydujesz z którego źródła korzystać i zapoznasz się z tym co tak na prawdę chcesz zrobić pojawi się kwestia co dokładnie chcesz uzyskać - disassembler działający na Z80 czy na "dużej" platformie?

Jeśli to pierwsze to zadanie jest dość ambitne choć jak pokazują przykłady jak najbardziej do zrobienia - gotowa procedura disassemblera była publikowana w książce "Mikroprocesor Z80" Jerzego Karczmarczuka i tej procedury (rozszerzonej o niepublikowane rozkazy) używaliśmy na Spectrum w "Summer Monitorze" i na Samie w eMonie.

Jeśli to drugie to masz znacznie większą swobodę i możliwości. Generalnie rozkazy są podzielone na grupy, które kodowane są na poszczególnych bitach w grupach rodzaj parametru, tryb adresowania i konkretny rozkaz kodowane są na kolejnych bitach do tego dochodzą oczywiście rozkazy prefiksowane CB/ED, które rozszerzają standardową listę oraz prefiksowanie dla rejestrów IX/IY, które HL zamienia na odpowiedni rejestr indeksowy z dodatkowym przesunięciem. Wszystko to opisane jest szczegółowo w oficjalnym manualu.

A disassembler to w sumie stosunkowo prosta sprawa... pobierasz bajt, sprawdzasz czy jest prefixem jeśli tak przeskakujesz do stosownej analizy pobierając następny bajt jeśli nie sprawdzasz poszczególne bity żeby namierzyć grupę, skaczesz do obsługi grupy, sprawdzasz bity, żeby ustalić parametry, pobierasz parametry zgodnie z tym i wszystko zamieniasz na tekst.


Frodo

  • *
  • Wiadomości: 18
Odp: Deasemblacja
« Odpowiedź #4 dnia: 2015.12.24, 12:52:03 »
Jak będę miał disasembler, to mogę mieć zaraz podstawowy emulator. Mam 7 tabel po 256 bajtów, jedna podstawowa i 6 z prefiksami. W tych tabelach będzie indeks jednego z 200 uogólnionych rozkazów. Taki rozkaz będzie strukturą, gdzie jedno pole to wskaźnik na funkcję. Czyli trzeba będzie dorobić 200 funkcji, ale można je tworzyć sukcesywnie, na razie wygenerowałem funkcje robiące tylko assert(false).

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Deasemblacja
« Odpowiedź #5 dnia: 2015.12.24, 13:27:14 »
Uuuu... Ciekawe podejście ;)

Weź pod uwagę, że Z80 jest zasadniczo automatem skończonym i to co robisz jest trochę pruciem na rympał a nie emulacją ;)
Ale pewnie też będzie działać :)

Frodo

  • *
  • Wiadomości: 18
Odp: Deasemblacja
« Odpowiedź #6 dnia: 2015.12.24, 13:52:55 »
A jak można robić inaczej? biorę rozkaz np. "xor b" odczytuję że dotyczy rejestru b oraz należy do rodziny rozkazów "xor R", dla tego wołam funkcję, która wykona mi xor i zwiększy IP. Może tu pewne niezrozumienie, ale to chyba jedyna możliwość emulacji poprzez interpretację, może działać z powodu tego, że PC jest znacznie szybsze niż Z80.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Deasemblacja
« Odpowiedź #7 dnia: 2015.12.24, 14:19:33 »
Oczywiście, że w uproszczeniu tak to właśnie działa, ale nie tablicujesz 7 razy po 256 kodów tylko tak jak Z80 dekodujesz co siedzi w danym rozkazie. Przejrzałeś opis listy rozkazów z manuala Ziloga do którego podawałem ci linka? Tam przy każdej grupie rozkazów jest informacja jakie bity w którym miejscu kodują dany rozkaz. I ładnie zrobiony emulator powinien to robić zgodnie z tym schematem. Oczywiście można też zrobić tak jak ty i zamiast ciąć bajt i analizować co z niego wynika stablicować wszystkie możliwe kombinacje. Będzie działać, ale nie będzie ładne ;)

Frodo

  • *
  • Wiadomości: 18
Odp: Deasemblacja
« Odpowiedź #8 dnia: 2015.12.24, 15:17:00 »
Ale tablica będzie działała dużo szybciej, przykładowo: mam bajt 0x83 = add a,e - zaglądam do tablicy i mam rozkaz.
Natomiast w Wiki mam podane add a,R = 10000rrr i te właśnie dane mam zapisane w alfabetycznej liście rozkazów. Te 7 tablic nie programuję bo to by było za dużo, ale mam alfabetyczną listę 200 rozkazów i na jej podstawie w programie generuję na początku te 256 elementowe tablice.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Deasemblacja
« Odpowiedź #9 dnia: 2015.12.24, 15:27:51 »
Ok. Tylko powiedz mi... na czym ty to będziesz odpalał? Na 286 z Herculesem? ;)

W dzisiejszych czasach na współczesnych maszynach przyspieszanie kodu przez zmniejszenie jego czytelności czy "elegancji" ma uzasadnienie jak się robi kod systemowy, który ma chodzić gdzieś pod spodem, cały czas i musi być jak najszybszy, żeby nie przeszkadzał użytkownikowi. Emulacja maszynki z procesorem 3.5 HMz na maszynie z zegarem powyżej gigaherca moim zdaniem nie wymaga aż takiej optymalizacji.

Ale może ja się zupełnie nie znam...
 

Frodo

  • *
  • Wiadomości: 18
Odp: Deasemblacja
« Odpowiedź #10 dnia: 2015.12.24, 20:43:19 »
Nie tylko chodzi o szybkość. Czy każdorazowe parsowanie nie tylko do emulacji ale i do wyświetlenia mnemonika to bardziej eleganckie rozwiązanie?
Mam już emulację 10-ciu z 200-tu instrukcji: są to ld,add,xor,call,ret i jp
Mam pytania odnośnie ustawiania flag:
- czy flagi zero i sign ustawiane przy operacjach arytmetycznych dotyczą tylko akumulatora? czy nie ma takich instrukcji jak xor c,d?
- co z nieużywanymi flagami, są ustawiane, nie ruszane, zerowane?
- nie wiem jak: H is set if carry from bit 3; otherwise, it is reset
- P / V is set if overflow; otherwise, it is reset
- C is set if carry from bit 7; otherwise, it is reset
Załączam emulację przykładu w trybie konsolowym w Visual Studio 2015.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Deasemblacja
« Odpowiedź #11 dnia: 2015.12.24, 23:45:03 »
RTFM. W manualu przy każdej instrukcji jest dokładnie rozpisane które flagi i w jakich warunkach są zmieniane.

Frodo

  • *
  • Wiadomości: 18
Odp: Deasemblacja
« Odpowiedź #12 dnia: 2015.12.25, 22:38:09 »
Nie wiem, czy w manualu nie jest błąd dla instrukcji cp czyli compare. W um0080.pdf mamy: "The s operand is any of r, n, (HL), (IX+d), or (lY+d), as defined for the analogous ADD instructions". Jaki sens instrukcji która dodaje a nie trzyma wyniku? Chyba raczej odejmuje, bo gdy w emulatorze ZXSpin wypróbowałem, to dla porównywania a z wartością, która jest w a ustawia się znacznik zera jak przy odejmowaniu. Chyba na pecetach instrukcje compare odejmują nie trzymając wyniku. Pisze co prawda o ustawianiu flagi zera, ale inne flagi też jak przy odejmowaniu? Również flaga N, ale nieudokumentowane flagi 3 i 5 ustawiają się jak jest w "a" a nie w odrzuconym wyniku. Więc jest drobna różnica od odejmowania.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Deasemblacja
« Odpowiedź #13 dnia: 2015.12.26, 00:09:36 »
"The s operand is any of r, n, (HL), (IX+d), or (lY+d), as defined for the analogous ADD instructions".

To jest odnośnik, który wyjaśnia, gdzie masz szukać szczegółowych informacji definiujących poszczególne operandy. Taki sam zapis jest przy wszystkich ośmiobitowych operacjach arytmetycznych oprócz ADD, gdzie poszczególne operandy są szczegółowo rozpisane.
Działanie instrukcji jest ciut wyżej pod " Operation" i tam napisane jest "jak wół" A - s. Opis ustawienia flag jest niżej i oczywiście jak pisałem masz tam tylko to, czego oficjalnie pozwalał używać Zilog - nieużywane flagi miały być nieużywane i ewentualnego ich opisu musisz szukać gdzie indziej.

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: Deasemblacja
« Odpowiedź #14 dnia: 2015.12.26, 00:10:41 »
Ale cp nic nie dodaje, tylko porównuje (ustawia flagi).