用C ++切换堆栈

时间:2009-05-15 01:38:18

标签: c++ winapi multiplestacks

我有一些使用Borland C ++用C语言编写的16位旧代码,它使用longjmps在多个堆栈之间切换。它通过执行malloc创建一个新堆栈,然后使用内联汇编程序将SS和SP寄存器设置为malloc'd区域地址的段和偏移量。我想将它转换为Win32,看起来两个指令应该由设置ESP的单个指令替换。这两条指令被CLI / STI对包围,但在Win32中这些指令给出了“特权指令”,所以我现在已将它们删除了。谈到Windows,我是一个真正无辜的人,所以,我对我的第一个测试案例的工作感到非常惊讶!所以,我相当模糊的问题是问这里的专家我做的是a)太危险了,或者b)如果我添加一些代码,采取一定的预防措施等会有效吗?如果是后者,应该添加什么,哪里可以找到它?我是否必须担心任何其他寄存器,如SS,EBX等?我正在使用没有优化...感谢您提供给我的任何提示。

5 个答案:

答案 0 :(得分:9)

由于操作环境的不同,删除CLI / STI仍然有效。

在16位DOS上,可能会发生中断,并且此中断最初将在同一堆栈上运行。如果在操作过程中被中断,则中断可能会崩溃,因为您只更新了s而不是sp。

在Windows和任何其他现代环境中,每个用户模式线程都有自己的堆栈。如果您的线程因任何原因而中断,它的堆栈和上下文将被安全地保留 - 您不必担心在您的线程和堆栈上运行其他东西。在这种情况下,cli / sti将防止您已经受到操作系统保护的内容。

正如Greg所说,在Windows上交换堆栈的安全,支持的方式是CreateFiber / SwitchToFiber。这确实会产生改变整个上下文的副作用,因此它不仅仅是切换堆栈。

这确实提出了你想做什么的问题。很多时候,切换堆栈是通过有限的堆栈空间获得的,在16位DOS上为64k。在Windows上,您有1 MB的堆栈,您可以分配更大的堆栈。你为什么试图切换堆栈?

答案 1 :(得分:5)

到目前为止,最安全的方法是将代码移植到官方的Win32多道程序结构,例如线程或光纤。 Fibers提供了一个非常轻量级的多堆栈范例,听起来它可能适合您的应用程序。

Why does Win32 even have fibers?文章也很有趣。

答案 2 :(得分:0)

我在用户模式下完成了这项工作,似乎没有任何问题。你不需要cli / sti,这些指令只是防止代码中的那一点发生中断,这对你告诉我们的有限信息来说是不必要的。

答案 3 :(得分:0)

请看Bert Hubert的Mtasker。它执行简单的协作式多任务处理,您可以很容易地使用它来移植代码。

答案 4 :(得分:0)

不要忘记跳跃堆栈将填充任何参数或堆栈驻留变量。