Napisałem kilka osób (asemblerów i dezasemblerów) i nie zacznę od x86. Jeśli znasz x86 lub jakikolwiek inny zestaw instrukcji, możesz pobrać i nauczyć się składni innego zestawu instrukcji w krótkim czasie (wieczór/popołudnie), przynajmniej jego udział w lwach.Czynność pisania asemblera (lub deasemblera) zdecydowanie nauczy cię zestawu instrukcji, szybko i będziesz wiedział, że ta instrukcja jest lepsza niż wielu doświadczonych programistów zestawów dla tego zestawu instrukcji, którzy nie zbadali mikrokodu na tym poziomie. msp430, pdp11 i kciuk (nie rozszerzenia thumb2) (lub mips lub openrisc) to dobre miejsce na rozpoczęcie, nie wiele instrukcji, niezbyt skomplikowane, itp.
Polecam najpierw dezasembler, a za nim zestaw instrukcji o ustalonej długości, taki jak ramię lub kciuk, czy mipy lub openrisc, itd. Jeśli nie, to przynajmniej użyj dezasemblera (zdecydowanie wybierz zestaw instrukcji, dla którego masz już asembler, linker i disasemsembler), a ołówkiem i papierem zrozumiesz związek między kodem maszynowym a złożeniem, w szczególności gałęzie, zwykle mają jedno lub więcej dziwactw, jak licznik programu jest instrukcją lub dwa naprzód po dodaniu przesunięcia, aby uzyskać inny bit, który czasami mierzy w całych instrukcjach, a nie bajtach.
Bardzo łatwo jest brutalnie zmatrzyć tekst za pomocą programu C, aby przeczytać instrukcje. Cięższym zadaniem, ale może także edukacyjnym, byłoby użycie bison/flex i nauczenie się tego języka programowania, aby umożliwić tym narzędziom tworzenie (jeszcze bardziej ekstremalnej brutalnej siły) parsera, który następnie łączy się z twoim kodem, by powiedzieć ci, co było znalezione.
Sam asembler jest dość prosty, wystarczy odczytać ascii i ustawić bity w kodzie maszynowym. Oddziały i inne instrukcje dotyczące komputera są trochę bardziej bolesne, ponieważ mogą wykonać wiele przejść przez źródło/tabele, aby całkowicie rozwiązać problem.
mov r0,r1
mov r2 ,#1
asembler zaczyna analizowania tekstu do linii (zdefiniowanych jako bajtów, które następują powrót karetki 0xD lub przewód doprowadzający 0xA), usunąć białe znaki (spacje i zakładek), aż dojdziesz do czegoś spoza białej spacja, a następnie strncmp to ze znanymi mnemonikami. jeśli uderzysz, przeanalizujesz możliwe kombinacje tej instrukcji, w prostym przypadku powyżej po przejściu mov przez białe spacje do nie-białej przestrzeni, być może pierwszą rzeczą, którą znajdziesz, musi być rejestr, następnie opcjonalna biała przestrzeń, a następnie przecinek. usuń białe znaki i przecinki i porównaj je z tabelą ciągów lub po prostu przeanalizuj ją. Gdy rejestr zostanie zakończony, przejdź obok miejsca, w którym znajduje się przecinek, i powiedz, że jest to inny rejestr lub natychmiastowy. Jeśli natychmiast powiemy, że musi mieć znak #, jeśli rejestr pozwala powiedzieć, że musi rozpoczynać się od małej lub dużej litery "r". po przeanalizowaniu tego rejestru lub natychmiast, upewnij się, że nie ma nic na linii, która nie powinna znajdować się na linii. zbuduj kod maszynowy dla tej instrukcji lub przynajmniej tyle, ile możesz i przejdź do następnej linii. Może to być uciążliwe, ale nie jest trudno przetworzyć dane ...
co najmniej potrzebujesz tabeli/tablicy, która gromadzi kod maszynowy/dane podczas ich tworzenia, oraz pewną metodę oznaczania instrukcji jako niekompletną , instrukcje dotyczące komputera, które należy ukończyć w przyszłym przebiegu. będziesz również chciał tabeli/tablicy, która zbiera znalezione etykiety i adres/offset w tabeli kodu maszynowego, gdzie został znaleziony. Oprócz etykiet użytych w instrukcji jako miejsca docelowego/źródła oraz przesunięcia w tabeli/macierzy zawierającej częściowo kompletne instrukcje, które zawierają. po pierwszym przejściu przejdź przez te tabele, aż dopasujesz wszystkie definicje etykiet z etykietami używanymi jako źródło lub miejsce docelowe, używając adresu definicji/odsunięcia etykiety, aby obliczyć odległość do danej instrukcji, a następnie dokończ tworzenie kod maszynowy dla tej instrukcji. (Może być wymagany jakiś demontaż i/lub inna metoda zapamiętania, jakiego rodzaju kodowania było, kiedy wrócisz do niego później, aby zakończyć tworzenie kodu maszynowego).
Następnym krokiem jest umożliwienie wielu plików źródłowych, jeśli jest to coś, na co chcesz zezwolić. Teraz musisz mieć etykiety, które nie zostaną rozwiązane przez asemblera, więc musisz zostawić symbole zastępcze na wyjściu i zrobić jakiś smak najdłuższego skoku/instrukcji rozgałęzienia, ponieważ nie wiesz, jak daleko będzie cel podróży, spodziewaj się gorzej.Następnie istnieje format pliku wyjściowego, który wybierzesz do utworzenia/użycia, a następnie linker, który jest w większości prosty, ale musisz pamiętać, aby wpisać kod maszynowy dla końcowych instrukcji względnych, nie trudniejszych niż był w asemblerze samo.
Uwaga, pisanie asemblera niekoniecznie jest związane z tworzeniem języka programowania, a następnie pisaniem dla niego kompilatora, osobną rzeczą, różnymi problemami. Właściwie, jeśli chcesz stworzyć nowy język programowania, po prostu użyj istniejącego asemblera dla istniejącego zestawu instrukcji. Oczywiście nie jest to wymagane, ale większość instrukcji i tutoriali będzie używać podejścia bison/flex dla języków programowania, a istnieje wiele wykładów i materiałów szkoleniowych dla początkujących klas kompilacji, których można użyć, aby zacząć, a następnie zmodyfikować skrypt, aby dodać funkcje Twojego języka. Środkowe i tylne końce stanowią większe wyzwanie niż front. istnieje wiele książek na ten temat i wiele zasobów internetowych. Jak wspomniano w innej odpowiedzi, llvm nie jest złym miejscem do stworzenia nowego języka programowania, w którym średnie i backendy są dla ciebie zrobione, wystarczy skupić się na samym języku programowania, na froncie.
Coś, o czym warto również pomyśleć: Finite Automata, aby sprawdzić, czy użytkownik używa nawet odpowiednich instrukcji, a także będzie potrzebny parser, aby upewnić się, że to, co pisze programista, jest poprawne. Chociaż istnieje wiele rzeczy po stronie systemu, które będą musiały się martwić, istnieje również wiele teorii obliczeń, które również trzeba znać. –
Może powinieneś studiować pakiet taki jak [NASM] (http://www.nasm.us/). –
Sprawdź [to wyzwanie w golfa kodowym] (http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu) dla zasobów 8086 i niezbyt krótkiego przykładowego programu z podzbiorem 8086 zarówno w formie źródłowej, jak i binarnej. IMO 1979 Manual to miejsce, od którego należy zacząć. ... Spójrz również na [moje pytanie na temat wiki zasobów montażowych] (http://stackoverflow.com/a/7203667/), w szczególności plik "PDP-1_Macro.pdf", który zawiera szczegółowy opis bardzo prymitywnego asemblera . –