Linux内核中是否存在需要有效用户空间堆栈的内容?也就是说,如果我以一种只访问数据段中的固定内存位置的方式编写程序,或者仅使用寄存器进行一些计算,我可以安全地将堆栈指针设置为0或其他无效地址,甚至是一个有效的地址,而不必担心那里的记忆会被覆盖?
其他问题:有没有人知道有关其他操作系统的问题的答案,例如: MacOS X,BSD,Windows?
答案 0 :(得分:1)
我怀疑任何人都可以很自信地告诉你这件事,但我会采取刺痛措施。
我的猜测是,技术上可以在没有堆叠的情况下运行但是获取正确的细节将非常困难。
中断和异常(例如页面错误)应该将寄存器保存到内核堆栈而不是用户空间堆栈,这样就没问题了。如果直接在汇编中编码,系统调用甚至可以工作。 (除非您在32位模式下运行并使用超过5个参数,在这种情况下,第六个是在用户堆栈上,但您仍然可以很容易地解决这个问题。)
显然调试很难; gdb希望你的堆栈安排如此。
要考虑的其他事项:
通常在启动时为您分配一个堆栈区域。不确定;您可以使用适当的链接器指令更改它。堆栈区域通常配置为向下增长。当在不在任何当前分配的区域中的地址处发生页面错误时,它假定要生长堆栈区域。错误地址不得小于sp
的值(即esp/rsp
)(少于64K软糖)。如果您不使用堆栈,我想这不是问题。
当您调用clone
系统调用来创建新任务(线程)时,您将为新任务提供堆栈指针。我不确定内核到底做了什么,看起来它只是填入新任务中的sp
寄存器(如果它非零)。这导致我...
clone
系统调用和许多其他系统未明确指定。 libc中嵌入了很多魔法来正确处理fork
,pthread_create
等等。如果你想创建额外的线程,你必须知道这种魔法并自己实现它。
信号处理期望能够将参数推送到用户空间堆栈。我不认为你可以在没有堆叠的情况下使用信号 - 或者至少它会非常复杂。