我有一些使用Borland C++用C语言编写的16位旧代码,它使用longjmps在多个堆栈之间切换.它通过执行malloc创建一个新堆栈,然后使用内联汇编程序将SS和SP寄存器设置为malloc'd区域地址的段和偏移量.我想将它转换为Win32,看起来两个指令应该由设置ESP的单个指令替换.这两条指令被CLI/STI对包围,但在Win32中这些指令给出了"特权指令",所以我现在已将它们删除了.谈到Windows,我是一个真正无辜的人,所以,我对我的第一个测试案例的工作感到非常惊讶!所以,我相当模糊的问题是问这里的专家,我在做什么是a)太危险了,或者b)如果我添加一些代码,采取一定的预防措施等会有效吗?如果是后者,应该添加什么,哪里可以找到它?我是否必须担心任何其他寄存器,如SS,EBX等?我使用没有优化...感谢任何提示的人可以给我.
由于操作环境的不同,删除CLI/STI仍然有效.
在16位DOS上,可能会发生中断,并且此中断最初将在同一堆栈上运行.如果在操作过程中被中断,则中断可能会崩溃,因为您只更新了s而不是sp.
在Windows和任何其他现代环境中,每个用户模式线程都有自己的堆栈.如果您的线程因任何原因而中断,它的堆栈和上下文将被安全地保留 - 您不必担心在您的线程和堆栈上运行其他东西.在这种情况下,cli/sti将保护您免受操作系统已经受到保护的攻击.
正如Greg所说,在Windows上交换堆栈的安全,支持的方式是CreateFiber/SwitchToFiber.这确实会产生改变整个上下文的副作用,因此它不仅仅是切换堆栈.
这确实提出了你想做什么的问题.很多时候,切换堆栈是通过有限的堆栈空间获得的,在16位DOS上为64k.在Windows上,您有1 MB的堆栈,您可以分配更大的堆栈.你为什么试图切换堆栈?
到目前为止,最安全的方法是将代码移植到官方的Win32多道程序结构,例如线程或光纤.纤维提供了一个非常轻量级的多堆栈范例,听起来它可能适合您的应用程序.
在为什么的Win32甚至有纤维?文章也很有趣.