这里有两个函数,前者负责保存和设置寄存器的值,以便手动切换协程栈到申请的堆上,并执行任务函数;后者在任务函数返回后将保存在堆中的栈指针值写回到寄存器上。程序会做 64 位和 32 位的编译。
static inline void stack_switch_call(struct co *co_ptr)
{
asm volatile(
#if __x86_64__
"movq %%rsp, 0x8(%0); movq %0, %%rsp; movq %2, %%rdi; call *%1"
:
: "b"((uintptr_t)co_ptr->stack + STACK_SIZE - 16), "d"(co_ptr->func), "a"(co_ptr->arg)
: "memory"
#else
"movl %%esp, 0x4(%0); movl %0, %%esp; movl %2, 0x0(%0); call *%1"
:
: "b"((uintptr_t)co_ptr->stack + STACK_SIZE - 12), "d"(co_ptr->func), "a"(co_ptr->arg)
: "memory"
#endif
);
}
static inline void restore_sp(struct co *co_ptr)
{
asm volatile(
#if __x86_64__
"movq %0, %%rsp"
:
: "b"((uintptr_t)co_ptr->stack + STACK_SIZE - 8)
: "memory"
#else
"movl %0, %%esp"
:
: "b"((uintptr_t)co_ptr->stack + STACK_SIZE - 8)
: "memory"
#endif
);
}
// 调用代码段
current_co->status = CO_RUNNING;
stack_switch_call(current_co);
restore_sp(current_co);
current_co->status = CO_DEAD;
经过 gdb 调试,stack_switch_call()
没有问题,保存的栈指针在堆上可以找到并打印出来。问题在于call
返回后restore_sp()
中的汇编指令无法调动,值写不回去。
想请教了解这方面知识的各位,restore_sp()
应该怎么写才可以呢?谢谢解惑
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.