Wiele lat temu spędziłem poranek próbując zdebugować jakiś samomodyfikujący się kod, jedna instrukcja zmieniła adres docelowy następnej instrukcji, tj. Obliczałem adres oddziału. Został napisany w języku asemblera i działał doskonale, kiedy przechodziłem przez program po jednej instrukcji na raz. Ale kiedy uruchomiłem program, nie udało się. W końcu zdałem sobie sprawę, że maszyna pobierała 2 instrukcje z pamięci i (ponieważ instrukcje były rozmieszczone w pamięci) instrukcja, którą modyfikowałem, została już pobrana, a zatem maszyna wykonywała niezmodyfikowaną (niepoprawną) wersję instrukcji. Oczywiście, kiedy debugowałem, wykonywałem tylko jedną instrukcję naraz.
Chodzi mi o to, że samomodyfikujący się kod może być wyjątkowo nieprzyjemny do testowania / debugowania i często ma ukryte założenia dotyczące zachowania maszyny (czy to sprzętowej, czy wirtualnej). Co więcej, system nigdy nie mógł udostępniać stron kodowych między różnymi wątkami / procesami wykonywanymi na (obecnie) maszynach wielordzeniowych. Eliminuje to wiele korzyści dla pamięci wirtualnej itp. Unieważniłoby również optymalizacje gałęzi wykonane na poziomie sprzętu.
(Uwaga - nie uwzględniam JIT w kategorii kodu samomodyfikującego się. JIT tłumaczy jedną reprezentację kodu na alternatywną reprezentację, nie modyfikuje kodu)
Podsumowując, to po prostu zły pomysł - naprawdę schludny, naprawdę niejasny, ale naprawdę zły.
oczywiście - jeśli wszystko, co masz, to 8080 i ~ 512 bajtów pamięci, być może będziesz musiał uciekać się do takich praktyk.