在x86-64下切换堆栈的最少代码是什么?我正在尝试在Windows和Linux下实现光纤,而没有getcontext或setjmp内联汇编.真的像交换$rsp和$rbp一样简单吗?因为我可以轻松做到这一点.我只是不确定如何去做.我对x86-64的知识knowledge之以鼻.
解决方法:
作为上下文切换的一部分,必须完成将RSP更改为指向不同堆栈的操作,该上下文切换从旧线程/光纤保存所有寄存器,并从新寄存器加载保存的体系结构状态.不只是RBP,还包括所有RAX-RDI和R8-R15以及RIP(通过jmp或ret).我想所有其他保留呼叫的架构状态,包括Windows x86-64上的xmm6-15.如果您的代码更改了MXCSR或x87控制寄存器,则也需要保存/恢复这些代码.
但是,如果将上下文切换放在noinline函数中,则编译器将为常规函数调用编写代码(该函数实际上会在稍后返回),并且函数调用已经破坏了所有被调用阻塞的寄存器.您不必保存调用者的zmm0-31,MPX bnd寄存器或RFLAGS.因此,使用xsaveopt / xrstor保存FPU / SIMD状态可能不值得.
如果您不修改其他reg,则会遇到不好的时光,因为切换到具有旧寄存器的新堆栈和新代码与从编译器下破坏调用保留的寄存器基本上是同一件事,即违反了ABI.
您不需要保存RFLAGS,因为在用户空间中唯一可以更改的是条件代码,而这些条件代码被调用了. ABI /调用约定已经要求在函数调用/返回时清除DF.