Hace muchos años, pasé una mañana tratando de depurar algún código auto-modificable, una instrucción cambió la dirección de destino de la siguiente instrucción, es decir, estaba calculando una dirección de sucursal. Estaba escrito en lenguaje ensamblador y funcionó perfectamente cuando revisé el programa una instrucción a la vez. Pero cuando ejecuté el programa falló. Finalmente, me di cuenta de que la máquina estaba obteniendo 2 instrucciones de la memoria y (como las instrucciones estaban colocadas en la memoria) la instrucción que estaba modificando ya había sido recuperada y, por lo tanto, la máquina estaba ejecutando la versión no modificada (incorrecta) de la instrucción. Por supuesto, cuando estaba depurando, solo estaba haciendo una instrucción a la vez.
Mi punto, el código auto-modificable puede ser extremadamente desagradable de probar / depurar y, a menudo, tiene suposiciones ocultas sobre el comportamiento de la máquina (ya sea hardware o virtual). Además, el sistema nunca podría compartir páginas de códigos entre los diversos subprocesos / procesos que se ejecutan en las (ahora) máquinas de múltiples núcleos. Esto anula muchos de los beneficios de la memoria virtual, etc. También invalidaría las optimizaciones de rama realizadas a nivel de hardware.
(Nota: no incluyo JIT en la categoría de código que se modifica automáticamente. JIT está traduciendo de una representación del código a una representación alternativa, no está modificando el código)
En general, es solo una mala idea, realmente ordenada, realmente oscura, pero realmente mala.
por supuesto, si todo lo que tiene son 8080 y ~ 512 bytes de memoria, es posible que tenga que recurrir a tales prácticas.