Переключение стеков в C ++ - PullRequest
7 голосов
/ 15 мая 2009

У меня есть некоторый старый код, написанный на C для 16-битной версии с использованием Borland C ++, который переключается между несколькими стеками, используя longjmps. Он создает новый стек, выполняя malloc, а затем устанавливает регистры SS и SP в сегмент и смещает, соответственно, адрес области malloc, используя встроенный Ассемблер. Я хотел бы преобразовать его в Win32, и похоже, что две инструкции должны быть заменены одной инструкцией, устанавливающей ESP. Эти две инструкции были окружены парой CLI / STI, но в Win32 они дают «привилегированные инструкции», поэтому я их пока исключил. Я действительно невиновен, когда дело доходит до Windows, поэтому я был довольно удивлен, что мой первый контрольный пример сработал! Итак, мой довольно расплывчатый вопрос заключается в том, чтобы спросить здесь экспертов, является ли то, что я делаю, а) слишком опасным для продолжения или б) сработает, если я добавлю некоторый код, приму определенные меры предосторожности и т. Д.? Если последнее, что следует добавить, и где я могу узнать об этом? Должен ли я беспокоиться о других регистрах, таких как SS, EBX и т. Д.? Я использую нет оптимизацию ... Спасибо за любые советы, которые люди могут дать мне.

Ответы [ 5 ]

9 голосов
/ 15 мая 2009

Удаление CLI / STI по-прежнему работает из-за различий в операционной среде.

В 16-битной DOS может произойти прерывание, и это прерывание будет первоначально работать в том же стеке. Если вы получили прерывание в середине операции, прерывание может произойти сбой, потому что вы обновили только ss, а не sp.

В Windows и любой другой современной среде каждый поток пользовательского режима получает свой собственный стек. Если ваш поток по какой-либо причине прерывается, его стек и контекст надежно сохраняются - вам не нужно беспокоиться о том, что что-то еще работает в вашем потоке и вашем стеке. cli / sti в этом случае будет защищать от того, от чего вы уже защищены ОС.

Как упоминал Грег, безопасный и поддерживаемый способ обмена стеками в Windows - это CreateFiber / SwitchToFiber. Это имеет побочный эффект изменения всего контекста, так что это не просто переключение стека.

Это действительно поднимает вопрос о том, что вы хотите сделать. Часто переключение стеков происходит с помощью ограниченного пространства стека, которое составляло 64 КБ в 16-разрядной DOS. В Windows у вас есть стек 1 МБ, и вы можете выделить еще больше. Почему вы пытаетесь переключать стеки?

5 голосов
/ 15 мая 2009

Безусловно, самый безопасный способ сделать это - перенести код на официальные многопрограммные структуры Win32, такие как потоки или волокна. Волокна обеспечивают очень легкую парадигму с несколькими стеками, которая звучит так, как будто она подходит для вашего приложения.

Почему в Win32 даже есть волокна? Статья тоже интересна для чтения.

0 голосов
/ 15 мая 2009

Не забывайте, что прыжковые стеки собирают любые аргументы или резидентные переменные стека.

0 голосов
/ 15 мая 2009

Взгляните на Mtasker Берт Хьюберт. Он выполняет простую совместную многозадачность, вам может быть легко использовать ее для переноса кода.

0 голосов
/ 15 мая 2009

Я сделал это в пользовательском режиме, и, похоже, проблем нет. Вы не нуждаетесь в cli / sti, эти инструкции просто предотвращают прерывания в этой точке кода, что не нужно из-за ограниченной информации, которую вы нам сообщили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...