V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Noicdi
V2EX  ›  C

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

  •  
  •   Noicdi · 2022-07-25 11:31:07 +08:00 · 1137 次点击
    这是一个创建于 844 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    想请教了解这方面知识的各位,restore_sp()应该怎么写才可以呢?谢谢解惑

    Noicdi
        1
    Noicdi  
    OP
       2022-07-25 14:11:54 +08:00
    没有老哥了解这方面吗
    Noicdi
        2
    Noicdi  
    OP
       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
        3
    Noicdi  
    OP
       2022-07-25 16:25:20 +08:00
    过了,我把 restore_sp() 里的汇编挪到 stack_switch_call() 的 call 指令后面,然后就行了
    Noicdi
        4
    Noicdi  
    OP
       2022-07-25 16:25:44 +08:00
    捏麻麻滴为什么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3889 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 04:13 · PVG 12:13 · LAX 20:13 · JFK 23:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.