(我认为这个问题很有可能是重复的,或者已经在这里得到了回答,但是由于“堆栈分配”和相关术语的干扰,很难找到答案。)
我有一个我一直在为脚本语言工作的玩具编译器。为了能够在脚本执行过程中暂停脚本的执行并返回到宿主程序,它有自己的堆栈:一个简单的内存块,带有一个“堆栈指针”变量,该变量使用正常的 C 代码操作递增诸如此类的事情等等。到目前为止不感兴趣。
目前我编译为 C。但我也有兴趣研究编译为机器代码 - 同时保持辅助堆栈和在预定义控制点返回主机程序的能力。
所以......我认为在我自己的代码中使用传统的堆栈寄存器不太可能成为问题,我假设寄存器发生的事情是我自己的事,只要一切都在完成后恢复(如果我在这一点上是错误的)。但是......如果我希望脚本代码调用其他一些库代码,那么使用这个“虚拟堆栈”离开程序是否安全,或者为此目的是否必须将原始堆栈归还?
像this和this这样的答案表明堆栈不是传统的内存块,而是依赖于特殊的系统特定行为来处理页面错误等等。
所以:
- 将堆栈指针移动到其他内存区域是否安全?堆栈内存不是“特殊”的吗?我认为线程库必须做这样的事情,因为它们会创建更多的堆栈......
- 假设内存的任何区域都可以安全地使用堆栈寄存器和指令进行操作,我认为没有理由调用具有已知调用深度(即没有递归,没有函数指针)的任何函数会成为问题,只要那个数量在虚拟堆栈上可用。对?
- 无论如何,堆栈溢出显然是普通代码中的一个问题,但是在这样的系统中溢出会产生任何额外的灾难性后果吗?
这显然不是必需的,因为简单地将指针返回到真正的堆栈将是完全可用的,或者就此而言,首先不要滥用它们而只是忍受更少的寄存器,我可能不应该尝试这样做完全没有(尤其是因为显然超出了我的理解范围)。但无论哪种方式,我仍然很好奇。想知道这些事情是如何工作的。
编辑:对不起,当然应该说。我正在研究 x86(我自己的机器为 32 位)、Windows 和 Ubuntu。没有什么异国情调。