Nhiều năm trước, tôi đã dành một buổi sáng để gỡ lỗi một số mã tự sửa đổi, một lệnh đã thay đổi địa chỉ đích của lệnh sau, tức là, tôi đang tính toán một địa chỉ chi nhánh. Nó được viết bằng hợp ngữ và hoạt động hoàn hảo khi tôi thực hiện từng bước một trong chương trình. Nhưng khi tôi chạy chương trình, nó không thành công. Cuối cùng, tôi nhận ra rằng máy đang tìm nạp 2 lệnh từ bộ nhớ và (như các lệnh đã được trình bày trong bộ nhớ) lệnh mà tôi đang sửa đổi đã được tìm nạp và do đó máy đang thực hiện phiên bản không sửa đổi (không chính xác) của lệnh. Tất nhiên, khi tôi đang gỡ lỗi, nó chỉ thực hiện một lệnh tại một thời điểm.
Quan điểm của tôi, mã tự sửa đổi có thể cực kỳ khó kiểm tra / gỡ lỗi và thường có các giả định ẩn về hoạt động của máy (có thể là phần cứng hoặc ảo). Hơn nữa, hệ thống không bao giờ có thể chia sẻ các trang mã giữa các luồng / quy trình khác nhau đang thực thi trên các máy đa lõi (hiện nay). Điều này làm mất đi nhiều lợi ích đối với bộ nhớ ảo, v.v. Nó cũng sẽ làm mất hiệu lực tối ưu hóa nhánh được thực hiện ở cấp phần cứng.
(Lưu ý - tôi không đưa JIT vào danh mục mã tự sửa đổi. JIT đang dịch từ một biểu diễn mã sang biểu diễn thay thế, nó không sửa đổi mã)
Nói chung, đó chỉ là một ý tưởng tồi - thực sự gọn gàng, thực sự tối nghĩa, nhưng thực sự tệ.
tất nhiên - nếu tất cả những gì bạn có là 8080 và ~ 512 byte bộ nhớ, bạn có thể phải sử dụng các phương pháp như vậy.