V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
jdz
V2EX  ›  Go 编程语言

刚接触 go,了解到切换协程仅需保存 3 个寄存器,那么剩余的怎么办呢,比如 ecx, eax 等

  •  
  •   jdz · 2022-07-09 13:47:05 +08:00 via Android · 3351 次点击
    这是一个创建于 648 天前的主题,其中的信息可能已经有所发展或是发生改变。

    go 只保存了,pc ,sp 和 dx

    8 条回复    2022-07-11 10:55:44 +08:00
    jdz
        1
    jdz  
    OP
       2022-07-09 14:01:35 +08:00 via Android
    是因为 go 与 java 一样都是基于栈的虚拟机?
    qbqbqbqb
        2
    qbqbqbqb  
       2022-07-09 14:52:16 +08:00
    应该是和 go 的调用约定有关,只保存被调用者保存( callee-saved )的寄存器,调用者保存( caller-saved )的寄存器是由函数本身生成的代码自己负责的。

    因为协程不是像线程那样由 OS 强行抢占的,是只有在特定的切换点才能切换,可以把这个切换的过程理解成一个特殊的函数调用 [而且 go 里面就有这么一个函数 runtime.Gosched()] 。caller-saved 寄存器如果需要保存的话,编译器会生成相应的代码,不用协程调度器保存。
    dearmymy
        3
    dearmymy  
       2022-07-09 15:10:14 +08:00
    这个跟 go 无关把。你协程本来也应该在函数内,其他寄存器在进入函数前都 pushall 了,只要协程能找回栈信息就能恢复把。
    GeruzoniAnsasu
        4
    GeruzoniAnsasu  
       2022-07-09 16:42:20 +08:00
    我有个印象,可能记错别太当真,就是,golang 会把函数内所有变量和参数都复制到栈上,所以可能只要 sp 指回来整个栈帧就能恢复
    iceheart
        5
    iceheart  
       2022-07-09 17:51:02 +08:00 via Android   ❤️ 1
    分版本,go1.15 之前用栈传参,go1.16 之后用寄存器传参了
    stach
        6
    stach  
       2022-07-09 18:43:37 +08:00
    我认为:剩余的寄存器,比如 ecx ,eax 等,协程切换时,保存在 go 的栈上。(不管是老的,还是新的调用规约)
    lovelylain
        7
    lovelylain  
       2022-07-09 19:40:30 +08:00 via Android
    eax ebx ecx edx 这些数据寄存器本来就不会跨函数吧,所以这几个是不需要保存的,不然每次函数调用也需要保存,代价太高。
    iamzuoxinyu
        8
    iamzuoxinyu  
       2022-07-11 10:55:44 +08:00
    Goroutine 中的寄存器并不是实际物理寄存器,Go 使用的寄存器是从 Plan 9 继承来的寄存器规范,跟物理寄存器并非 1:1 严格映射的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5073 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 03:55 · PVG 11:55 · LAX 20:55 · JFK 23:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.