Jakiś czas temu stworzyłem prosty komputer symulowany. Miał peryferia, bufor ekranu, który mógł być renderowany do tekstury OpenGL, oraz kilka innych fajnych funkcji. Działa, działa dobrze i ogólnie jestem z tego całkiem zadowolony.Bezpieczny, skuteczny typ danych podstawowych dla prostej maszyny wirtualnej
Z wyjątkiem, oszukałem.
Podstawowy typ danych to połączenie liczby całkowitej, zmiennoprzecinkowej i typu instrukcji (podzielone na pola bitowe).
Dla każdego poprawnego (symulowanego) programu, związek zawsze jest używany bezpiecznie, tylko czytając od ostatniego członka związku zapisanego w. Jednak potencjał, że źle uformowane programu (np ładowane z symulowanym twardym dysku) może uzyskać dostęp do członków out of order może narazić mnie na zwykłych problemów związanych z nadużywaniem UNION:
- możliwość, że zapis może być zoptymalizowane w czasie kompilacji - kompilator nie może mieć wystarczającej ilości informacji, aby próbować tej optymalizacji.
- Wartość odczytana z unii może być śmieciem - jest to całkowicie dopuszczalne zachowanie dla mnie.
- Odczytany w ten sposób wskaźnik może być wartością sygnalizującą-NaN/pułapkę - jest to poważny problem - awarie symulowanego komputera są w porządku, ale awarie programu są katastrofalne.
- To jest technicznie niezdefiniowane zachowanie, więc chociaż prawdopodobnie nie będzie, może ustawić komputer w ogniu, usunąć dysk twardy lub przywołać Cthulhu.
Solutions rozważyć:
- Kłucie z unii - Może to wystarczająco dobrze zdefiniowane dla wszystkich platform świata rzeczywistego? Być może są sposoby na dezynfekcję sNaNs?
- Oznaczone połączenie - skutecznie zmniejszy ilość pamięci w połowie
- Oddzielnie przechowywana tablica efektywnie zapakowanych tagów - trochę skrzypliwie propaguje znacznik, ale poza tym jest nieco żywotna.
- tablica znaków - wydaje się prosta, ale koszty zrobienia tego bezpiecznie, pozwalając na odczyt z innego rodzaju niż ten, który został napisany, naprawdę sumują się.
- Typ całkowity - jak wyżej w przypadku danych zmiennoprzecinkowych i instrukcji, z tą różnicą, że liczby całkowite są trywialne.
- tablica znaków plus oddzielne rejestry liczb całkowitych i zmiennoprzecinkowych - charakterystyczne i pod wieloma względami idealne, ale wymagałoby ode mnie napisania kompilatora, który mógłby z nich efektywnie korzystać.
Wyobrażam sobie, że jest to projekt, który wielu użytkowników SO podjęło lub nie podjęło, dlatego szczególnie mile widziane są specyficzne problemy.
Co rozumiesz przez "podstawowy typ danych"? Podstawowy typ danych rzeczywistej maszyny to 99,9999% czasu uint8_t – James
@James - right, aw moim kompilatorze uint8_t to tylko typedef do unsigned char, który jest jedną z opcji, które rozważam. Ale nawet wtedy większość maszyn wykonuje operacje arytmetyczne na operandach 32- lub 64-bitowych. – DeveloperInDevelopment
Możesz napisać swoją maszynę wirtualną w C. C umożliwia czytanie ze związków w znacznie bardziej zrelaksowany sposób niż w C++. –