如何将保存在堆中的值写入寄存器

2022-07-25 11:31:07 +08:00
 Noicdi

这里有两个函数,前者负责保存和设置寄存器的值,以便手动切换协程栈到申请的堆上,并执行任务函数;后者在任务函数返回后将保存在堆中的栈指针值写回到寄存器上。程序会做 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()应该怎么写才可以呢?谢谢解惑

1032 次点击
所在节点    C
4 条回复
Noicdi
2022-07-25 14:11:54 +08:00
没有老哥了解这方面吗
Noicdi
2022-07-25 15:41:13 +08:00
补充在 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)
Noicdi
2022-07-25 16:25:20 +08:00
过了,我把 restore_sp() 里的汇编挪到 stack_switch_call() 的 call 指令后面,然后就行了
Noicdi
2022-07-25 16:25:44 +08:00
捏麻麻滴为什么

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/868499

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX