И что это нам дает? Придется делать выход за пределы обработчика NMI и уже там сначала выключать ПЗУ с обработчиком NMI, и затем делать RET? А этот доп. обработчик класть в ОЗУ где вероятно полезный код прерванного по NMI приложения? Который тоже сохранять (а где?), и как его восстанавливать если мы пришли сюда сделать RET? Какая-то бесконечная рекурсия.
По-другому, надо делать: обработчик NMI весь держать в той же дополнительной ОЗУ или ПЗУ, включающейся по NMI, и аппаратно ловить выполнение команды RETI (упрощая - RET), по которой аппаратно опрокидывать триггер (отключать NMI-ПЗУ). Тогда на момент чтения со стека адреса возврата все в адресном пространстве уже будет в начальном состоянии.
Или ваще не париться на предмет где там был стек. Мы эмулируем СПЕК (MSX), а значит знаем где у них ПЗУ и где гарантированно не будет стека. Там же и обработчик NMI разместить. Со Cпеком тут все просто, у него с 0000 идет ПЗУ. А где ПЗУ у MSX?
- - - Добавлено - - -
Кстати, метод "переодически ставить стек на ПЗУ" (если там реальное ПЗУ с известным кодом куски которого {например найти их поиском} задействовать под адреса возвратов) можно использовать как защиту от гипервизоров, реализованных на NMI: прерванный такой код вообще нигде не сохранит адрес возврата и не будет понятно куда возвращать управление.![]()






Ответить с цитированием