这里有两个函数,前者负责保存和设置寄存器的值,以便手动切换协程栈到申请的堆上,并执行任务函数;后者在任务函数返回后将保存在堆中的栈指针值写回到寄存器上。程序会做 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()
应该怎么写才可以呢?谢谢解惑
1
Noicdi OP 没有老哥了解这方面吗
|
2
Noicdi OP 补充在 32bit 的错误
![32]( https://xqmq--blog-image.oss-cn-shenzhen.aliyuncs.com/blog-image/v2ex-error-2.png) 然后通过直接写栈指针的方式,确认思路正确,定位问题到:怎么把栈指针的值写回去 ![32]( https://xqmq--blog-image.oss-cn-shenzhen.aliyuncs.com/blog-image/v2ex-error-1.png) |
3
Noicdi OP 过了,我把 restore_sp() 里的汇编挪到 stack_switch_call() 的 call 指令后面,然后就行了
|
4
Noicdi OP 捏麻麻滴为什么
|